Merge pull request #105 from hartsock/issue/72
Malformed XML fails in informative ways.
This commit is contained in:
@@ -16,7 +16,7 @@ from __future__ import absolute_import
|
|||||||
|
|
||||||
from six import PY2
|
from six import PY2
|
||||||
from six import PY3
|
from six import PY3
|
||||||
|
from six import reraise
|
||||||
from six.moves import http_client
|
from six.moves import http_client
|
||||||
|
|
||||||
if PY3:
|
if PY3:
|
||||||
@@ -442,6 +442,32 @@ class SoapSerializer:
|
|||||||
self.writer.write('</{0}>'.format(info.name))
|
self.writer.write('</{0}>'.format(info.name))
|
||||||
|
|
||||||
|
|
||||||
|
class ParserError(KeyError):
|
||||||
|
# NOTE (hartsock): extends KeyError since parser logic is written to
|
||||||
|
# catch KeyError types. Normally, I would want PerserError to be a root
|
||||||
|
# type for all parser faults.
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ReadDocument(parser, data):
|
||||||
|
# NOTE (hartsock): maintaining library internal consistency here, this is
|
||||||
|
# a refactoring that rolls up some repeated code blocks into a method so
|
||||||
|
# that we can refactor XML parsing behavior in a single place.
|
||||||
|
if not isinstance(data, str):
|
||||||
|
data = data.read()
|
||||||
|
try:
|
||||||
|
parser.Parse(data)
|
||||||
|
except Exception:
|
||||||
|
# wrap all parser faults with additional information for later
|
||||||
|
# bug reporting on the XML parser code itself.
|
||||||
|
(ec, ev, tb) = sys.exc_info()
|
||||||
|
line = parser.CurrentLineNumber
|
||||||
|
col = parser.CurrentColumnNumber
|
||||||
|
pe = ParserError("xml document: "
|
||||||
|
"{0} parse error at: "
|
||||||
|
"line:{1}, col:{2}".format(data, line, col))
|
||||||
|
# use six.reraise for python 2.x and 3.x compatability
|
||||||
|
reraise(ParserError, pe, tb)
|
||||||
|
|
||||||
## Deserialize an object from a file or string
|
## Deserialize an object from a file or string
|
||||||
#
|
#
|
||||||
# This function will deserialize one top-level XML node.
|
# This function will deserialize one top-level XML node.
|
||||||
@@ -453,10 +479,7 @@ def Deserialize(data, resultType=object, stub=None):
|
|||||||
parser = ParserCreate(namespace_separator=NS_SEP)
|
parser = ParserCreate(namespace_separator=NS_SEP)
|
||||||
ds = SoapDeserializer(stub)
|
ds = SoapDeserializer(stub)
|
||||||
ds.Deserialize(parser, resultType)
|
ds.Deserialize(parser, resultType)
|
||||||
if isinstance(data, str):
|
ReadDocument(parser, data)
|
||||||
parser.Parse(data)
|
|
||||||
else:
|
|
||||||
parser.ParseFile(data)
|
|
||||||
return ds.GetResult()
|
return ds.GetResult()
|
||||||
|
|
||||||
|
|
||||||
@@ -582,11 +605,7 @@ class SoapDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
if not self.stack:
|
if not self.stack:
|
||||||
if self.isFault:
|
if self.isFault:
|
||||||
ns, name = self.SplitTag(tag)
|
ns, name = self.SplitTag(tag)
|
||||||
try:
|
objType = self.LookupWsdlType(ns, name[:-5])
|
||||||
objType = self.LookupWsdlType(ns, name[:-5])
|
|
||||||
except KeyError:
|
|
||||||
message = "{0} was not found in the WSDL".format(name[:-5])
|
|
||||||
raise VmomiMessageFault(message)
|
|
||||||
# Only top level soap fault should be deserialized as method fault
|
# Only top level soap fault should be deserialized as method fault
|
||||||
deserializeAsLocalizedMethodFault = False
|
deserializeAsLocalizedMethodFault = False
|
||||||
else:
|
else:
|
||||||
@@ -761,10 +780,7 @@ class SoapResponseDeserializer(ExpatDeserializerNSHandlers):
|
|||||||
nsMap = {}
|
nsMap = {}
|
||||||
self.nsMap = nsMap
|
self.nsMap = nsMap
|
||||||
SetHandlers(self.parser, GetHandlers(self))
|
SetHandlers(self.parser, GetHandlers(self))
|
||||||
if isinstance(response, str):
|
ReadDocument(self.parser, response)
|
||||||
self.parser.Parse(response)
|
|
||||||
else:
|
|
||||||
self.parser.ParseFile(response)
|
|
||||||
result = self.deser.GetResult()
|
result = self.deser.GetResult()
|
||||||
if self.isFault:
|
if self.isFault:
|
||||||
if result is None:
|
if result is None:
|
||||||
@@ -1241,10 +1257,15 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
# The server is probably sick, drop all of the cached connections.
|
# The server is probably sick, drop all of the cached connections.
|
||||||
self.DropConnections()
|
self.DropConnections()
|
||||||
raise
|
raise
|
||||||
cookie = resp.getheader('Set-Cookie')
|
# NOTE (hartsocks): this cookie handling code should go away in a future
|
||||||
|
# release. The string 'set-cookie' and 'Set-Cookie' but both are
|
||||||
|
# acceptable, but the supporting library may have a bug making it
|
||||||
|
# case sensitive when it shouldn't be. The term 'set-cookie' will occur
|
||||||
|
# more frequently than 'Set-Cookie' based on practical testing.
|
||||||
|
cookie = resp.getheader('set-cookie')
|
||||||
if cookie is None:
|
if cookie is None:
|
||||||
# try lower-case header for backwards compat. with old vSphere
|
# try case-sensitive header for compatibility
|
||||||
cookie = resp.getheader('set-cookie')
|
cookie = resp.getheader('Set-Cookie')
|
||||||
status = resp.status
|
status = resp.status
|
||||||
|
|
||||||
if cookie:
|
if cookie:
|
||||||
@@ -1257,12 +1278,18 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
fd = GzipReader(resp, encoding=GzipReader.GZIP)
|
fd = GzipReader(resp, encoding=GzipReader.GZIP)
|
||||||
elif encoding == 'deflate':
|
elif encoding == 'deflate':
|
||||||
fd = GzipReader(resp, encoding=GzipReader.DEFLATE)
|
fd = GzipReader(resp, encoding=GzipReader.DEFLATE)
|
||||||
obj = SoapResponseDeserializer(outerStub).Deserialize(fd, info.result)
|
deserializer = SoapResponseDeserializer(outerStub)
|
||||||
except:
|
obj = deserializer.Deserialize(fd, info.result)
|
||||||
|
except Exception as exc:
|
||||||
conn.close()
|
conn.close()
|
||||||
|
# NOTE (hartsock): This feels out of place. As a rule the lexical
|
||||||
|
# context that opens a connection should also close it. However,
|
||||||
|
# in this code the connection is passed around and closed in other
|
||||||
|
# contexts (ie: methods) that we are blind to here. Refactor this.
|
||||||
|
|
||||||
# The server might be sick, drop all of the cached connections.
|
# The server might be sick, drop all of the cached connections.
|
||||||
self.DropConnections()
|
self.DropConnections()
|
||||||
raise
|
raise exc
|
||||||
else:
|
else:
|
||||||
resp.read()
|
resp.read()
|
||||||
self.ReturnConnection(conn)
|
self.ReturnConnection(conn)
|
||||||
@@ -1343,6 +1370,9 @@ class SoapStubAdapter(SoapStubAdapterBase):
|
|||||||
self.lock.release()
|
self.lock.release()
|
||||||
else:
|
else:
|
||||||
self.lock.release()
|
self.lock.release()
|
||||||
|
# NOTE (hartsock): this seems to violate good coding practice in that
|
||||||
|
# the lexical context that opens a connection should also be the
|
||||||
|
# same context responsible for closing it.
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
## Disable nagle on a http connections
|
## Disable nagle on a http connections
|
||||||
|
@@ -1012,6 +1012,13 @@ def GetWsdlType(ns, name):
|
|||||||
|
|
||||||
raise KeyError("{0} {1}".format(ns, name))
|
raise KeyError("{0} {1}".format(ns, name))
|
||||||
|
|
||||||
|
|
||||||
|
class UnknownWsdlTypeError(KeyError):
|
||||||
|
# NOTE (hartsock): KeyError is extended here since most logic will be
|
||||||
|
# looking for the KeyError type. I do want to distinguish malformed WSDL
|
||||||
|
# errors as a separate classification of error for easier bug reports.
|
||||||
|
pass
|
||||||
|
|
||||||
## Guess the type from wsdlname with no ns
|
## Guess the type from wsdlname with no ns
|
||||||
# WARNING! This should not be used in general, as there is no guarantee for
|
# WARNING! This should not be used in general, as there is no guarantee for
|
||||||
# the correctness of the guessing type
|
# the correctness of the guessing type
|
||||||
@@ -1026,8 +1033,8 @@ def GuessWsdlType(name):
|
|||||||
try:
|
try:
|
||||||
return GetWsdlType(ns, name)
|
return GetWsdlType(ns, name)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
raise KeyError(name)
|
raise UnknownWsdlTypeError(name)
|
||||||
|
|
||||||
## Return a map that contains all the wsdl types
|
## Return a map that contains all the wsdl types
|
||||||
# This function is rarely used
|
# This function is rarely used
|
||||||
|
274
tests/fixtures/test_unknown_fault.yaml
vendored
Normal file
274
tests/fixtures/test_unknown_fault.yaml
vendored
Normal file
@@ -0,0 +1,274 @@
|
|||||||
|
interactions:
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><RetrieveServiceContent xmlns="urn:vim25"><_this type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrieveServiceContentResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><perfManager
|
||||||
|
type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager></returnval></RetrieveServiceContentResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Length: ['3332']
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:40 GMT']
|
||||||
|
Set-Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><Login xmlns="urn:vim25"><_this type="SessionManager">SessionManager</_this><userName>my_user</userName><password>my_password</password></Login></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<LoginResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><key>52c20b61-24c3-f233-a549-d36d3ae68e14</key><userName>my_user</userName><fullName>my_user
|
||||||
|
</fullName><loginTime>2014-07-29T18:58:41.001537Z</loginTime><lastActiveTime>2014-07-29T18:58:41.001537Z</lastActiveTime><locale>en</locale><messageLocale>en</messageLocale></returnval></LoginResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Length: ['665']
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:41 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><RetrieveServiceContent xmlns="urn:vim25"><_this type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrieveServiceContentResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><perfManager
|
||||||
|
type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager></returnval></RetrieveServiceContentResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Length: ['3332']
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:41 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><RetrieveServiceContent xmlns="urn:vim25"><_this type="ServiceInstance">ServiceInstance</_this></RetrieveServiceContent></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrieveServiceContentResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><rootFolder type=\"Folder\">group-d1</rootFolder><propertyCollector
|
||||||
|
type=\"PropertyCollector\">propertyCollector</propertyCollector><viewManager
|
||||||
|
type=\"ViewManager\">ViewManager</viewManager><about><name>VMware vCenter
|
||||||
|
Server</name><fullName>VMware vCenter Server 5.5.0 build-1750787 (Sim)</fullName><vendor>VMware,
|
||||||
|
Inc.</vendor><version>5.5.0</version><build>1750787 (Sim)</build><localeVersion>INTL</localeVersion><localeBuild>000</localeBuild><osType>linux-x64</osType><productLineId>vpx</productLineId><apiType>VirtualCenter</apiType><apiVersion>5.5</apiVersion><instanceUuid>EAB4D846-C243-426B-A021-0547644CE59D</instanceUuid><licenseProductName>VMware
|
||||||
|
VirtualCenter Server</licenseProductName><licenseProductVersion>5.0</licenseProductVersion></about><setting
|
||||||
|
type=\"OptionManager\">VpxSettings</setting><userDirectory type=\"UserDirectory\">UserDirectory</userDirectory><sessionManager
|
||||||
|
type=\"SessionManager\">SessionManager</sessionManager><authorizationManager
|
||||||
|
type=\"AuthorizationManager\">AuthorizationManager</authorizationManager><perfManager
|
||||||
|
type=\"PerformanceManager\">PerfMgr</perfManager><scheduledTaskManager type=\"ScheduledTaskManager\">ScheduledTaskManager</scheduledTaskManager><alarmManager
|
||||||
|
type=\"AlarmManager\">AlarmManager</alarmManager><eventManager type=\"EventManager\">EventManager</eventManager><taskManager
|
||||||
|
type=\"TaskManager\">TaskManager</taskManager><extensionManager type=\"ExtensionManager\">ExtensionManager</extensionManager><customizationSpecManager
|
||||||
|
type=\"CustomizationSpecManager\">CustomizationSpecManager</customizationSpecManager><customFieldsManager
|
||||||
|
type=\"CustomFieldsManager\">CustomFieldsManager</customFieldsManager><diagnosticManager
|
||||||
|
type=\"DiagnosticManager\">DiagMgr</diagnosticManager><licenseManager type=\"LicenseManager\">LicenseManager</licenseManager><searchIndex
|
||||||
|
type=\"SearchIndex\">SearchIndex</searchIndex><fileManager type=\"FileManager\">FileManager</fileManager><virtualDiskManager
|
||||||
|
type=\"VirtualDiskManager\">virtualDiskManager</virtualDiskManager><snmpSystem
|
||||||
|
type=\"HostSnmpSystem\">SnmpSystem</snmpSystem><vmProvisioningChecker type=\"VirtualMachineProvisioningChecker\">ProvChecker</vmProvisioningChecker><vmCompatibilityChecker
|
||||||
|
type=\"VirtualMachineCompatibilityChecker\">CompatChecker</vmCompatibilityChecker><ovfManager
|
||||||
|
type=\"OvfManager\">OvfManager</ovfManager><ipPoolManager type=\"IpPoolManager\">IpPoolManager</ipPoolManager><dvSwitchManager
|
||||||
|
type=\"DistributedVirtualSwitchManager\">DVSManager</dvSwitchManager><hostProfileManager
|
||||||
|
type=\"HostProfileManager\">HostProfileManager</hostProfileManager><clusterProfileManager
|
||||||
|
type=\"ClusterProfileManager\">ClusterProfileManager</clusterProfileManager><complianceManager
|
||||||
|
type=\"ProfileComplianceManager\">MoComplianceManager</complianceManager><localizationManager
|
||||||
|
type=\"LocalizationManager\">LocalizationManager</localizationManager><storageResourceManager
|
||||||
|
type=\"StorageResourceManager\">StorageResourceManager</storageResourceManager></returnval></RetrieveServiceContentResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Length: ['3332']
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:41 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><RetrievePropertiesEx xmlns="urn:vim25"><_this type="PropertyCollector">propertyCollector</_this><specSet><propSet><type>LicenseManager</type><all>false</all><pathSet>licenseAssignmentManager</pathSet></propSet><objectSet><obj
|
||||||
|
type="LicenseManager">LicenseManager</obj><skip>false</skip></objectSet></specSet><options><maxObjects>1</maxObjects></options></RetrievePropertiesEx></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<soapenv:Envelope
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"\n xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"\n
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n<soapenv:Body>\n<RetrievePropertiesExResponse
|
||||||
|
xmlns=\"urn:vim25\"><returnval><objects><obj type=\"LicenseManager\">LicenseManager</obj><propSet><name>licenseAssignmentManager</name><val
|
||||||
|
type=\"LicenseAssignmentManager\" xsi:type=\"ManagedObjectReference\">LicenseAssignmentManager</val></propSet></objects></returnval></RetrievePropertiesExResponse>\n</soapenv:Body>\n</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Length: ['652']
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:41 GMT']
|
||||||
|
status: {code: 200, message: OK}
|
||||||
|
- request:
|
||||||
|
body: '<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
|
||||||
|
|
||||||
|
<soapenv:Body><QueryAssignedLicenses xmlns="urn:vim25"><_this type="LicenseAssignmentManager">LicenseAssignmentManager</_this></QueryAssignedLicenses></soapenv:Body>
|
||||||
|
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
headers:
|
||||||
|
Accept-Encoding: ['gzip, deflate']
|
||||||
|
Content-Type: [text/xml; charset=UTF-8]
|
||||||
|
Cookie: ['vmware_soap_session="52d6ea56-0052-259f-e3f6-8ea7a7f349cb"; Path=/;
|
||||||
|
HttpOnly; Secure; ']
|
||||||
|
SOAPAction: ['"urn:vim25/4.1"']
|
||||||
|
method: POST
|
||||||
|
uri: https://vcsa:443/sdk
|
||||||
|
response:
|
||||||
|
body: {string: "<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<soapenv:Envelope
|
||||||
|
xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"
|
||||||
|
xmlns:soapenc=\"http://schemas.xmlsoap.org/soap/encoding/\"
|
||||||
|
xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"
|
||||||
|
xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">
|
||||||
|
<soapenv:Body>
|
||||||
|
<soapenv:Fault>
|
||||||
|
<faultcode>ServerFaultCode</faultcode>
|
||||||
|
<faultstring/>
|
||||||
|
<detail>
|
||||||
|
<UnknownLicenseProblemFaultFault xsi:type=\"UnknownLicenseProblemFault\">
|
||||||
|
<reason>unknownReason</reason></UnknownLicenseProblemFaultFault>
|
||||||
|
</detail>
|
||||||
|
</soapenv:Fault>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>"}
|
||||||
|
headers:
|
||||||
|
Cache-Control: [no-cache]
|
||||||
|
Connection: [Keep-Alive]
|
||||||
|
Content-Type: [text/xml; charset=utf-8]
|
||||||
|
Date: ['Tue, 29 Jul 2014 18:58:41 GMT']
|
||||||
|
Transfer-Encoding: [chunked]
|
||||||
|
status: {code: 500, message: Internal Server Error}
|
||||||
|
version: 1
|
55
tests/test_fault_deserializer.py
Normal file
55
tests/test_fault_deserializer.py
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# VMware vSphere Python SDK
|
||||||
|
# Copyright (c) 2008-2014 VMware, Inc. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
from tests import fixtures_path
|
||||||
|
import unittest
|
||||||
|
import vcr
|
||||||
|
|
||||||
|
from pyVim import connect
|
||||||
|
from pyVmomi import SoapStubAdapter
|
||||||
|
from pyVmomi import vim
|
||||||
|
|
||||||
|
class DeserializerTests(unittest.TestCase):
|
||||||
|
|
||||||
|
@vcr.use_cassette('test_unknown_fault.yaml',
|
||||||
|
cassette_library_dir=fixtures_path, record_mode='once')
|
||||||
|
def test_unknown_fault(self):
|
||||||
|
# see: http://python3porting.com/noconv.html
|
||||||
|
si = connect.Connect(host='vcsa',
|
||||||
|
user='my_user',
|
||||||
|
pwd='my_password')
|
||||||
|
content = si.RetrieveContent()
|
||||||
|
lm = content.licenseManager
|
||||||
|
# NOTE (hartsock): assertIsNotNone does not work in Python 2.6
|
||||||
|
self.assertTrue(lm is not None)
|
||||||
|
lam = lm.licenseAssignmentManager
|
||||||
|
# NOTE (hartsock): assertIsNotNone does not work in Python 2.6
|
||||||
|
self.assertTrue(lam is not None)
|
||||||
|
# cassette is altered to raise a fault here:
|
||||||
|
fault = None
|
||||||
|
try:
|
||||||
|
lam.QueryAssignedLicenses()
|
||||||
|
except Exception as ex:
|
||||||
|
# NOTE (hartsock): not using 'assertRaises' so we can inspect obj
|
||||||
|
fault = ex
|
||||||
|
# NOTE (hartsock): assertIsNotNone does not work in Python 2.6
|
||||||
|
self.assertTrue(fault is not None) # only until 2.6 support is dropped.
|
||||||
|
# Observe that the malformed XML was reported up the stack to the
|
||||||
|
# user so that field reports will contain SOAP message information.
|
||||||
|
self.assertTrue('<detail> '
|
||||||
|
'<UnknownLicenseProblemFaultFault '
|
||||||
|
'xsi:type="UnknownLicenseProblemFault"> '
|
||||||
|
'<reason>unknownReason</reason>'
|
||||||
|
'</UnknownLicenseProblemFaultFault> '
|
||||||
|
'</detail>' in str(fault))
|
Reference in New Issue
Block a user