|
From: <ma...@us...> - 2015-01-23 00:22:28
|
Revision: 728
http://sourceforge.net/p/pywbem/code/728
Author: maiera
Date: 2015-01-23 00:22:25 +0000 (Fri, 23 Jan 2015)
Log Message:
-----------
Fixed timeout support added in r727;
Added -t TIMEOUT option to test_cim_operations.py;
Restructured exceptions raised by WBEMConnections;
Added all exceptions that can be raised by WBEMConnections, to the pywbem namespace.
Revision Links:
--------------
http://sourceforge.net/p/pywbem/code/727
Modified Paths:
--------------
pywbem/trunk/pywbem/NEWS
pywbem/trunk/pywbem/__init__.py
pywbem/trunk/pywbem/cim_http.py
pywbem/trunk/pywbem/cim_operations.py
pywbem/trunk/testsuite/test_cim_operations.py
Modified: pywbem/trunk/pywbem/NEWS
===================================================================
--- pywbem/trunk/pywbem/NEWS 2015-01-22 18:21:33 UTC (rev 727)
+++ pywbem/trunk/pywbem/NEWS 2015-01-23 00:22:25 UTC (rev 728)
@@ -1,4 +1,4 @@
-pywbem-0.8.0-dev.r727
+pywbem-0.8.0-dev.r728
ENHANCEMENTS:
@@ -84,7 +84,8 @@
of WBEMConnection class for details. (Andreas Maier)
* Added support for timeouts to WBEMConnection, via a new timeout argument,
- that defaults to no timeout. (Andreas Maier)
+ that defaults to no timeout. (This finally increased the minimum version
+ of Python to 2.6. (Andreas Maier)
BUG FIXES:
Modified: pywbem/trunk/pywbem/__init__.py
===================================================================
--- pywbem/trunk/pywbem/__init__.py 2015-01-22 18:21:33 UTC (rev 727)
+++ pywbem/trunk/pywbem/__init__.py 2015-01-23 00:22:25 UTC (rev 728)
@@ -133,6 +133,10 @@
PyWBEM has been tested with Python 2.7 on Windows and Linux, and with Python
2.6 on Linux (due to a restriction of the `M2Crypto` package on Windows).
+Python 2.6 is the minimum version of Python that is supported.
+
+Python 3 is not yet supported.
+
Contributing
------------
@@ -160,8 +164,8 @@
from pywbem.cim_operations import *
from pywbem.cim_obj import *
from pywbem.tupleparse import ParseError
+from pywbem.cim_http import Error, ConnectionError, AuthError, TimeoutError
-# TODO: Check if we can bump the minimum Python version to 2.6.
import sys
-if sys.version_info < (2,3,0):
- raise RuntimeError('PyWBEM requires Python 2.3.0 or higher')
+if sys.version_info < (2,6,0):
+ raise RuntimeError('PyWBEM requires Python 2.6.0 or higher')
Modified: pywbem/trunk/pywbem/cim_http.py
===================================================================
--- pywbem/trunk/pywbem/cim_http.py 2015-01-22 18:21:33 UTC (rev 727)
+++ pywbem/trunk/pywbem/cim_http.py 2015-01-23 00:22:25 UTC (rev 728)
@@ -49,23 +49,24 @@
from pywbem import cim_obj
-__all__ = ['Error', 'AuthError', 'wbem_request', 'get_object_header']
+__all__ = ['Error', 'ConnectionError', 'AuthError', 'TimeoutError',
+ 'HTTPTimeout', 'wbem_request', 'get_object_header']
class Error(Exception):
- """This exception is raised when a transport error occurs."""
+ """Exception base class for catching any HTTP transport related errors."""
pass
+class ConnectionError(Error):
+ """This exception is raised when there is a problem with the connection
+ to the server. A retry may or may not succeed."""
+ pass
+
class AuthError(Error):
"""This exception is raised when an authentication error (401) occurs."""
pass
-class ConnectionError(Error):
- """This exception is raised when a connection-related problem occurs,
- where a retry might make sense."""
- pass
-
class TimeoutError(Error):
- """This exception is raised when the client timeout is exceeded."""
+ """This exception is raised when the client times out."""
pass
class HTTPTimeout (object):
@@ -97,13 +98,14 @@
self._timeout = timeout
self._http_conn = http_conn
- self._retrytime = 10 # time in seconds after which a retry of the
+ self._retrytime = 5 # time in seconds after which a retry of the
# socket shutdown is scheduled if the socket
# is not yet on the connection when the
# timeout expires initially.
- self._timer = None
- self._ts1 = None
- self._expired = None
+ self._timer = None # the timer object
+ self._ts1 = None # timestamp when timer was started
+ self._shutdown = None # flag indicating that the timer handler has
+ # shut down the socket
return
def __enter__(self):
@@ -112,40 +114,44 @@
HTTPTimeout.timer_expired, [self])
self._timer.start()
self._ts1 = datetime.now()
- self._expired = False
+ self._shutdown = False
return
def __exit__(self, exc_type, exc_value, traceback):
if self._timeout != None:
self._timer.cancel()
- if self._expired:
+ if self._shutdown:
+ # If the timer handler has shut down the socket, we
+ # want to make that known, and override any other
+ # exceptions that may be pending.
ts2 = datetime.now()
duration = ts2 - self._ts1
duration_sec = float(duration.microseconds)/1000000 +\
duration.seconds + duration.days*24*3600
- raise TimeoutError("Timeout error: Client timed out after "\
- "%.0fs." % duration_sec)
+ raise TimeoutError("The client timed out and closed the "\
+ "socket after %.0fs." % duration_sec)
return False # re-raise any other exceptions
def timer_expired(self):
"""
This method is invoked in context of the timer thread, so we cannot
directly throw exceptions (we can, but they would be in the wrong
- thread), so instead we cause the socket of the connection to shut down.
+ thread), so instead we shut down the socket of the connection.
+ When the timeout happens in early phases of the connection setup,
+ there is no socket object on the HTTP connection yet, in that case
+ we retry after the retry duration, indefinitely.
+ So we do not guarantee in all cases that the overall operation times
+ out after the specified timeout.
"""
- self._expired = True
if self._http_conn.sock != None:
- # Timer expired, shutting down socket of HTTP connection.
+ self._shutdown = True
self._http_conn.sock.shutdown(socket.SHUT_RDWR)
else:
- # Timer expired, no socket yet on HTTP connection to shut down,
- # so we retry. This should only happen with very short timeouts,
- # so retrying should not hurt, timewise.
+ # Retry after the retry duration
self._timer.cancel()
self._timer = threading.Timer(self._retrytime,
HTTPTimeout.timer_expired, [self])
self._timer.start()
- return
def parse_url(url):
"""Return a tuple of ``(host, port, ssl)`` from the URL specified in the
@@ -302,14 +308,17 @@
A value of ``None`` means there is no timeout.
A value of ``0`` means the timeout is very short, and does not really
make any sense.
+ Note that not all situations can be handled within this timeout, so
+ for some issues, this method may take longer to raise an exception.
:Returns:
The CIM-XML formatted response data from the WBEM server, as a `unicode`
object.
:Raises:
- :raise Error:
:raise AuthError:
+ :raise ConnectionError:
+ :raise TimeoutError:
"""
class HTTPBaseConnection:
@@ -329,12 +338,13 @@
self.sock.sendall(str)
class HTTPConnection(HTTPBaseConnection, httplib.HTTPConnection):
- def __init__(self, host, port=None, strict=None):
+ def __init__(self, host, port=None, strict=None, timeout=None):
httplib.HTTPConnection.__init__(self, host, port, strict, timeout)
class HTTPSConnection(HTTPBaseConnection, httplib.HTTPSConnection):
def __init__(self, host, port=None, key_file=None, cert_file=None,
- strict=None, ca_certs=None, verify_callback=None):
+ strict=None, ca_certs=None, verify_callback=None,
+ timeout=None):
httplib.HTTPSConnection.__init__(self, host, port, key_file,
cert_file, strict, timeout)
self.ca_certs = ca_certs
@@ -345,14 +355,18 @@
# Calling httplib.HTTPSConnection.connect(self) does not work
# because of its ssl.wrap_socket() call. So we copy the code of
- # that connect() method modulo the ssl.wrap_socket() call:
- if sys.version_info[0:2] == [2, 7]:
- self.sock = socket.create_connection((self.host, self.port),
- self.timeout,
- self.source_address)
- else: # 2.6
- self.sock = socket.create_connection((self.host, self.port),
- self.timeout)
+ # that connect() method modulo the ssl.wrap_socket() call.
+ #
+ # Another change is that we do not pass the timeout value
+ # on to the socket call, because that does not work with M2Crypto.
+ if sys.version_info[0:2] >= (2, 7):
+ # the source_address argument was added in 2.7
+ self.sock = socket.create_connection(
+ (self.host, self.port), None, self.source_address)
+ else:
+ self.sock = socket.create_connection(
+ (self.host, self.port), None)
+
if self._tunnel_host:
self._tunnel()
# End of code from httplib.HTTPSConnection.connect(self).
@@ -373,6 +387,20 @@
# Below is a body of SSL.Connection.connect() method
# except for the first line (socket connection). We want to
# preserve tunneling ability.
+
+ # Setting the timeout on the input socket does not work
+ # with M2Crypto, with such a timeout set it calls a different
+ # low level function (nbio instead of bio) that does not work.
+ # the symptom is that reading the response returns None.
+ # Therefore, we set the timeout at the level of the outer
+ # M2Crypto socket object.
+ if False: # Currently disabled
+ if self.timeout is not None:
+ self.sock.set_socket_read_timeout(
+ SSL.timeout(self.timeout))
+ self.sock.set_socket_write_timeout(
+ SSL.timeout(self.timeout))
+
self.sock.addr = (self.host, self.port)
self.sock.setup_ssl()
self.sock.set_connect_state()
@@ -382,12 +410,13 @@
self.sock.clientPostConnectionCheck)
if check is not None:
if not check(self.sock.get_peer_cert(), self.host):
- raise Error('SSL error: post connection check '\
- 'failed')
+ raise ConnectionError(
+ 'SSL error: post connection check failed')
return ret
except (Err.SSLError, SSL.SSLError, SSL.Checker.WrongHost), arg:
# This will include SSLTimeoutError (it subclasses SSLError)
- raise Error("SSL error %s: %s" % (str(arg.__class__), arg))
+ raise ConnectionError(
+ "SSL error %s: %s" % (str(arg.__class__), arg))
class FileHTTPConnection(HTTPBaseConnection, httplib.HTTPConnection):
@@ -399,8 +428,9 @@
try:
socket_af = socket.AF_UNIX
except AttributeError:
- raise Error('file URL not supported on %s platform due '\
- 'to missing AF_UNIX support' % platform.system())
+ raise ConnectionError(
+ 'file URLs not supported on %s platform due '\
+ 'to missing AF_UNIX support' % platform.system())
self.sock = socket.socket(socket_af, socket.SOCK_STREAM)
self.sock.connect(self.uds_path)
@@ -447,16 +477,16 @@
timeout=timeout)
else:
if url.startswith('file:'):
- url = url[5:]
+ url_ = url[5:]
try:
- s = os.stat(url)
+ s = os.stat(url_)
if S_ISSOCK(s.st_mode):
- h = FileHTTPConnection(url)
+ h = FileHTTPConnection(url_)
local = True
else:
- raise Error('Invalid URL: %s' % url)
- except OSError:
- raise Error('Invalid URL: %s' % url)
+ raise ConnectionError('File URL is not a socket: %s' % url)
+ except OSError as exc:
+ raise ConnectionError('Error with file URL %s: %s' % (url, exc))
locallogin = None
if host in ('localhost', 'localhost6', '127.0.0.1', '::1'):
@@ -505,12 +535,16 @@
# to our fixed HTTPConnection classes, we'll still be able to
# retrieve the response so that we can read and respond to the
# authentication challenge.
- h.endheaders()
+
try:
+ # endheaders() is the first method in this sequence that
+ # actually sends something to the server.
+ h.endheaders()
h.send(data)
- except socket.error, arg:
- if arg[0] != 104 and arg[0] != 32:
- raise
+ except socket.error as exc:
+ # TODO: Verify these errno numbers on Windows vs. Linux
+ if exc[0] != 104 and exc[0] != 32:
+ raise ConnectionError("Socket error: %s" % exc)
response = h.getresponse()
@@ -526,10 +560,11 @@
try:
uid = os.getuid()
except AttributeError:
- raise Error("OWLocal authorization for "\
- "openwbem server not supported "\
- "on %s platform due to missing "\
- "os.getuid()" % platform.system())
+ raise ConnectionError(
+ "OWLocal authorization for OpenWbem "\
+ "server not supported on %s platform "\
+ "due to missing os.getuid()" %\
+ platform.system())
localAuthHeader = ('Authorization',
'OWLocal uid="%d"' % uid)
continue
@@ -570,47 +605,45 @@
continue
except ValueError:
pass
-
raise AuthError(response.reason)
- if response.getheader('CIMError', None) is not None and \
- response.getheader('PGErrorDetail', None) is not None:
- raise Error(
- 'CIMError: %s: %s' %
- (response.getheader('CIMError'),
- urllib.unquote(response.getheader(
- 'PGErrorDetail'))))
- raise Error('HTTP error: %s' % response.reason)
+ cimerror_hdr = response.getheader('CIMError', None)
+ if cimerror_hdr is not None:
+ exc_str = 'CIMError: %s' % cimerror_hdr
+ pgerrordetail_hdr = response.getheader('PGErrorDetail',
+ None)
+ if pgerrordetail_hdr is not None:
+ exc_str += ', PGErrorDetail: %s' %\
+ urllib.unquote(pgerrordetail_hdr)
+ raise ConnectionError(exc_str)
+
+ raise ConnectionError('HTTP error: %s' % response.reason)
+
body = response.read()
- except httplib.BadStatusLine, arg:
+ except httplib.BadStatusLine as exc:
# Background: BadStatusLine is documented to be raised only
# when strict=True is used (that is not the case here).
# However, httplib currently raises BadStatusLine also
# independent of strict when a keep-alive connection times out
# (e.g. because the server went down).
# See http://bugs.python.org/issue8450.
- # On how to detect this: A connection timeout definitely causes
- # arg==None, but it is not clear whether other situations could
- # also cause arg==None.
- if arg.line.strip().strip("'") == '':
- raise ConnectionError("Connection error: The CIM server "\
- "closed the connection without "\
- "returning any data, or the client "\
- "timed out")
+ if exc.line is None or exc.line.strip().strip("'") in \
+ ('', 'None'):
+ raise ConnectionError("The server closed the "\
+ "connection without returning any data, or the "\
+ "client timed out")
else:
- raise Error("HTTP error: The CIM server returned a bad "\
- "HTTP status line: '%s'" % arg.line)
- except httplib.IncompleteRead, arg:
- raise ConnectionError("Connection error: HTTP incomplete "\
- "read: %s" % arg)
- except httplib.NotConnected, arg:
- raise ConnectionError("Connection error: HTTP not "\
- "connected: %s" % arg)
- except socket.error, arg:
- raise ConnectionError("Connection error: Socket error %s" %arg)
- except socket.sslerror, arg:
- raise ConnectionError("Connection error: SSL error %s" % arg)
+ raise ConnectionError("The server returned a bad "\
+ "HTTP status line: %r" % exc.line)
+ except httplib.IncompleteRead as exc:
+ raise ConnectionError("HTTP incomplete read: %s" % exc)
+ except httplib.NotConnected as exc:
+ raise ConnectionError("HTTP not connected: %s" % exc)
+ except socket.error as exc:
+ raise ConnectionError("Socket error: %s" % exc)
+ except socket.sslerror as exc:
+ raise ConnectionError("SSL error: %s" % exc)
break
Modified: pywbem/trunk/pywbem/cim_operations.py
===================================================================
--- pywbem/trunk/pywbem/cim_operations.py 2015-01-22 18:21:33 UTC (rev 727)
+++ pywbem/trunk/pywbem/cim_operations.py 2015-01-23 00:22:25 UTC (rev 728)
@@ -191,7 +191,7 @@
cpos1 = max(ic_pos-context_before,0)
cpos2 = min(ic_pos+context_after,len(utf8_xml))
exc_txt += ", CIM-XML snippet: %r" % utf8_xml[cpos1:cpos2]
- raise tupleparse.ParseError(exc_txt)
+ raise ParseError(exc_txt)
# Check for incorrectly encoded UTF-8 sequences.
# @ibm.13@ Simplified logic (removed loop).
@@ -213,7 +213,7 @@
cpos1 = max(_p1-context_before,0)
cpos2 = min(_p2+context_after,len(utf8_xml))
exc_txt += ", CIM-XML snippet: %r" % utf8_xml[cpos1:cpos2]
- raise tupleparse.ParseError(exc_txt)
+ raise ParseError(exc_txt)
# Now we know the Unicode characters are valid.
# Check for Unicode characters that cannot legally be represented as XML
@@ -233,53 +233,31 @@
cpos2 = min(ic_pos+context_after,len(utf8_xml_u))
exc_txt += "\n At offset %d: U+%04X, CIM-XML snippet: %r" % \
(ic_pos, ord(ic_char), utf8_xml_u[cpos1:cpos2])
- raise tupleparse.ParseError(exc_txt)
+ raise ParseError(exc_txt)
return utf8_xml
-class CIMError(Exception):
+class CIMError(cim_http.Error):
"""
- Exception indicating that either the WBEM server has returned an error or
- the response from the WBEM server has some issue.
+ Exception indicating that the WBEM server has returned an error response
+ with a CIM status code.
The exception value is a tuple of
``(error_code, description, exception_obj)``, where:
- * ``error_code``: a numeric error code. See below for details.
+ * ``error_code``: the numeric CIM status code. See `cim_constants` for
+ constants defining CIM status code values.
* ``description``: a string (`unicode` or UTF-8 encoded `str`)
- representing a human readable message describing the error. See below
- for details.
+ that is the CIM status description text returned by the server,
+ representing a human readable message describing the error.
* ``exception_obj``: the underlying exception object that caused this
- exception to be raised. See below for details.
-
- An ``error_code`` value other than 0 indicates that the WBEM server has
- returned an error response, and ``error_code`` is the CIM status code of
- the error response. See `cim_constants` for constants defining CIM status
- code values. In this case, ``description`` is the CIM status description
- text returned by the server, and ``exception_obj`` is ``None``.
-
- An ``error_code`` value of 0 indicates an error detected in the PyWBEM
- client after receiving the response returned by the WBEM server (for
- example, an XML parsing error). In this case, ``exception_obj`` is another
- exception object describing the error, and ``description`` is the
- string representation of the error message of that other exception object.
- The following other exception objects are used:
-
- * `cim_http.AuthError`: Authentication error (HTTP status 401).
- * `cim_http.ConnectionError`: Problem with the connection to the server,
- a retry sometimes later would make sense.
- * `cim_http.TimeoutError`: Client timeout occurred.
- * `tupleparse.ParseError`: CIM-XML parsing issue.
- * `cim_http.Error`: Other low level error (e.g. HTTP error, CIMError
- HTTP header). This exception is a base class for `cim_http.AuthError`,
- `cim_http.ConnectionError`, and `cim_http.TimeoutError` and thus must
- be handled at the end.
+ exception to be raised, or ``None``. Will always be ``None``.
"""
+ pass
-
class WBEMConnection(object):
"""
A client's connection to a WBEM server. This is the main class of the
@@ -321,44 +299,30 @@
* Exceptions indicating processing errors:
- - `pywbem.Error` - HTTP transport error.
+ - `pywbem.ConnectionError` - A connection with the WBEM server could not
+ be established or broke down.
- `pywbem.AuthError` - Authentication failed with the WBEM server.
- - `pywbem.CIMError` - CIM error.
+ - `pywbem.ParseError` - The response from the WBEM server cannot be
+ parsed (for example, invalid characters or UTF-8 sequences, ill-formed
+ XML, or invalid CIM-XML).
- With an ``error_code`` value of 0, the reason is one of:
+ - `pywbem.CIMError` - The WBEM server returned an error response with a
+ CIM status code.
- * Error in the arguments of a method.
- * Connection problem with the WBEM server.
- * HTTP-level errors reported by the WBEM server (except for HTTP
- transport errors and authentication failures).
+ - `pywbem.TimeoutError` - The WBEM server did not respond in time and the
+ client timed out.
- With other ``error_code`` values, the reason is always that the
- operation invoked on the WBEM server failed and returned a CIM error.
- For the possible CIM errors that can be returned by each operation, see
- DMTF DSP0200.
+ * Exceptions indicating programming errors:
- - `pywbem.ParseError` - CIM-XML parsing problem in the response from
- the WBEM server. The exception message provides details.
- Possible reasons are:
-
- * Response contains ill-formed UTF-8 Byte sequences (uses surrogates).
- * Response contains incorrectly encoded UTF-8 Byte sequences.
- * Response contains invalid XML characters (e.g. ``\\x00`` or
- ``�``).
- * Response is not well-formed XML.
- * Response does not validate against the CIM-XML DTD/schema.
-
- * Exceptions indicating programming errors in PyWBEM or layers below:
-
- `TypeError`
- `KeyError`
- `ValueError`
- ... possibly others ...
Exceptions indicating programming errors should not happen and should be
- reported as bugs.
+ reported as bugs, unless caused by the code using this class.
:Ivariables:
@@ -516,10 +480,16 @@
Timeout in seconds, for requests sent to the server. If the server
did not respond within the timeout duration, the socket for the
connection will be closed, causing a `TimeoutError` to be raised.
+
A value of ``None`` means there is no timeout.
+
A value of ``0`` means the timeout is very short, and does not
really make any sense.
+ Note that not all situations can be handled within this timeout, so
+ for some issues, operations may take longer before raising an
+ exception.
+
:Exceptions:
See the list of exceptions described in `WBEMConnection`.
@@ -621,8 +591,8 @@
no_verification=self.no_verification,
timeout=self.timeout)
except (cim_http.AuthError, cim_http.ConnectionError,
- cim_http.TimeoutError, cim_http.Error) as exc:
- raise CIMError(0, str(exc), exc)
+ cim_http.TimeoutError, cim_http.Error):
+ raise
# Set the raw response before parsing (which can fail)
if self.debug:
@@ -651,13 +621,13 @@
# we call it also when debug is turned on.
try:
check_utf8_xml_chars(reply_xml, "CIM-XML response")
- except ParseError as exc2:
- raise CIMError(0, str(exc2), exc2)
+ except ParseError:
+ raise
else:
if parsing_error:
# We did not catch it in the check function, but
# minidom.parseString() failed.
- raise CIMError(0, msg, exc) # data from previous exception
+ raise ParseError(msg) # data from previous exception
if self.debug:
pretty_reply = reply_dom.toprettyxml(indent=' ')
@@ -669,29 +639,24 @@
tt = tupleparse.parse_cim(tupletree.dom_to_tupletree(reply_dom))
if tt[0] != 'CIM':
- exc = ParseError('Expecting CIM element, got %s' % tt[0])
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting CIM element, got %s' % tt[0])
tt = tt[2]
if tt[0] != 'MESSAGE':
- exc = ParseError('Expecting MESSAGE element, got %s' % tt[0])
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting MESSAGE element, got %s' % tt[0])
tt = tt[2]
if len(tt) != 1 or tt[0][0] != 'SIMPLERSP':
- exc = ParseError('Expecting one SIMPLERSP element')
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting one SIMPLERSP element')
tt = tt[0][2]
if tt[0] != 'IMETHODRESPONSE':
- exc = ParseError('Expecting IMETHODRESPONSE element, got %s' %\
+ raise ParseError('Expecting IMETHODRESPONSE element, got %s' %\
tt[0])
- raise CIMError(0, str(exc), exc)
if tt[1]['NAME'] != methodname:
- exc = ParseError('Expecting attribute NAME=%s, got %s' %\
+ raise ParseError('Expecting attribute NAME=%s, got %s' %\
(methodname, tt[1]['NAME']))
- raise CIMError(0, str(exc), exc)
tt = tt[2]
# At this point we either have a IRETURNVALUE, ERROR element
@@ -708,8 +673,7 @@
raise CIMError(code, 'Error code %s' % tt[1]['CODE'])
if tt[0] != 'IRETURNVALUE':
- exc = ParseError('Expecting IRETURNVALUE element, got %s' % tt[0])
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting IRETURNVALUE element, got %s' % tt[0])
return tt
@@ -838,8 +802,8 @@
no_verification=self.no_verification,
timeout=self.timeout)
except (cim_http.AuthError, cim_http.ConnectionError,
- cim_http.TimeoutError, cim_http.Error) as exc:
- raise CIMError(0, str(exc), exc)
+ cim_http.TimeoutError, cim_http.Error):
+ raise
# Set the raw response before parsing and checking (which can fail)
if self.debug:
@@ -868,13 +832,13 @@
# we call it also when debug is turned on.
try:
check_utf8_xml_chars(reply_xml, "CIM-XML response")
- except ParseError as exc2:
- raise CIMError(0, str(exc2), exc2)
+ except ParseError:
+ raise
else:
if parsing_error:
# We did not catch it in the check function, but
# minidom.parseString() failed.
- raise CIMError(0, msg, exc) # data from previous exception
+ raise ParseError(msg) # data from previous exception
if self.debug:
pretty_reply = reply_dom.toprettyxml(indent=' ')
@@ -886,29 +850,24 @@
tt = tupleparse.parse_cim(tupletree.dom_to_tupletree(reply_dom))
if tt[0] != 'CIM':
- exc = ParseError('Expecting CIM element, got %s' % tt[0])
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting CIM element, got %s' % tt[0])
tt = tt[2]
if tt[0] != 'MESSAGE':
- exc = ParseError('Expecting MESSAGE element, got %s' % tt[0])
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting MESSAGE element, got %s' % tt[0])
tt = tt[2]
if len(tt) != 1 or tt[0][0] != 'SIMPLERSP':
- exc = ParseError('Expecting one SIMPLERSP element')
- raise CIMError(0, str(exc), exc)
+ raise ParseError('Expecting one SIMPLERSP element')
tt = tt[0][2]
if tt[0] != 'METHODRESPONSE':
- exc = ParseError('Expecting METHODRESPONSE element, got %s' %\
+ raise ParseError('Expecting METHODRESPONSE element, got %s' %\
tt[0])
- raise CIMError(0, str(exc), exc)
if tt[1]['NAME'] != methodname:
- exc = ParseError('Expecting attribute NAME=%s, got %s' %\
+ raise ParseError('Expecting attribute NAME=%s, got %s' %\
(methodname, tt[1]['NAME']))
- raise CIMError(0, str(exc), exc)
tt = tt[2]
# At this point we have an optional RETURNVALUE and zero or
Modified: pywbem/trunk/testsuite/test_cim_operations.py
===================================================================
--- pywbem/trunk/testsuite/test_cim_operations.py 2015-01-22 18:21:33 UTC (rev 727)
+++ pywbem/trunk/testsuite/test_cim_operations.py 2015-01-23 00:22:25 UTC (rev 728)
@@ -32,14 +32,14 @@
def setup(self):
"""Create a connection."""
+ global url, username, password, namespace, timeout
- # Use globals url, username and password
-
self.system_url = url
self.conn = WBEMConnection(
self.system_url,
(username, password),
- namespace)
+ namespace,
+ timeout=timeout)
self.conn.debug = True
def cimcall(self, fn, *args, **kw):
@@ -791,7 +791,8 @@
if __name__ == '__main__':
if len(sys.argv) < 2:
- print 'Usage for manual external tests:\n %s [OPTS] URL [USERNAME%%PASSWORD [COMFYOPTS] '\
+ print 'Usage for manual external tests:\n'\
+ ' %s [OPTS] URL [USERNAME%%PASSWORD [COMFYOPTS] '\
'[COMFYTESTS]]' % sys.argv[0]
print 'Invoke with -h or --help for full help text.'
print 'Running internal tests...'
@@ -821,6 +822,8 @@
print ' --help, -h Display this help text.'
print ' -n NAMESPACE Use this CIM namespace instead of '\
'default: %s' % DEFAULT_NAMESPACE
+ print ' -t TIMEOUT Use this timeout (in seconds) instead '\
+ 'of no timeout'
print ''
print 'Comfychair help:'
print ''
@@ -834,6 +837,7 @@
sys.exit(0)
namespace = DEFAULT_NAMESPACE
+ timeout = None
while (True):
if sys.argv[1][0] != '-':
# Stop at first non-option
@@ -841,6 +845,9 @@
if sys.argv[1] == '-n':
namespace = sys.argv[2]
del sys.argv[1:3]
+ elif sys.argv[1] == '-t':
+ timeout = int(sys.argv[2])
+ del sys.argv[1:3]
else:
print "Error: Unknown option: %s" % sys.argv[1]
sys.exit(1)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|