reorganize tests - run on installed suds version + do not require py2to3
The test suite is no longer installed together with the project and can now be run from the project's source distribution. This resolves the issue of the suds test suite confusing users by getting installed as a top level tests package in their Python environment. Project to be tested now need to be explicitly installed prior to running its tests using pytest, except in case of Python 2 tests being run from the top level project folder. This requires the user to install the project (suggested way is to install it in editable mode using 'pip install -e') but also allows him to run the tests on other non-sandbox project versions, e.g. an externally installed version. Project testing now requires the six Python 2/3 compatibility support package (installed automatically, together with other test requirements). Test support code now moved to a separate testutils package located under the tests folder. Updated project README.rst & HACKING.rst docs. Minor stylistic changes.
This commit is contained in:
parent
34bcf2a476
commit
1618ae351f
194
HACKING.rst
194
HACKING.rst
|
@ -102,7 +102,7 @@ TOP-LEVEL PROJECT FILES & FOLDERS
|
|||
module search path) the same as if installed using ``easy_install -e`` or
|
||||
``pip install -e``
|
||||
``setup.py test``
|
||||
run the project's test suite (requires ``pytest``)
|
||||
run the project test suite (requires ``pytest``)
|
||||
|
||||
|
||||
PYTHON COMPATIBILITY
|
||||
|
@ -114,6 +114,10 @@ states aiming for Python 2.4 compatibility we should do so as well.
|
|||
The Python 3.0 minor release is not supported. See `Python 3.0 support`_
|
||||
subsection below for more detailed information.
|
||||
|
||||
Test & setup code needs to be implemented using Python 2 & 3 compatible source
|
||||
code. Setup & setup related scripts need to be implemented so they do not rely
|
||||
on other pre-installed libraries.
|
||||
|
||||
These backward compatibility requirements do not affect internal development
|
||||
operations such as ``setup.py`` support for uploading a new project distribution
|
||||
package to PyPI. Such operations need to be supported on the latest Python 2 & 3
|
||||
|
@ -286,25 +290,23 @@ respectively.
|
|||
Setting up the development & testing environment
|
||||
------------------------------------------------
|
||||
|
||||
``tools/setup_base_environments.py`` script should be used for setting up your
|
||||
basic Python environments so they support testing our project. The script can
|
||||
be configured configured from the main project Python configuration file
|
||||
``setup.cfg``. It implements all the backward compatibility tweaks that would
|
||||
otherwise need to be done manually in order to be able to test our project in
|
||||
those environments. These tweaks are no longer documented elsewhere so anyone
|
||||
interested in the details should consult the script's sources.
|
||||
``tools/setup_base_environments.py`` script should be used for setting up the
|
||||
basic Python environments so they support testing our project. The script can be
|
||||
configured from the main project Python configuration file ``setup.cfg``. It
|
||||
implements all the backward compatibility tweaks and performs additional
|
||||
required package installation that would otherwise need to be done manually in
|
||||
order to be able to test our project in those environments.
|
||||
|
||||
Project's test suite requires the ``pytest`` testing framework to run. The test
|
||||
code base is compatible with pytest 2.4.0+ (prior versions do not support
|
||||
non-string ``skipif`` expressions).
|
||||
These exact requirements and their related version specific tweaks are not
|
||||
documented elsewhere so anyone interested in the details should consult the
|
||||
script's sources.
|
||||
|
||||
The testing environment is generally set up as follows:
|
||||
|
||||
1. Install Python.
|
||||
#. Install ``setuptools`` (using ``setup_ez.py`` or from its source
|
||||
distribution).
|
||||
#. Install ``pip`` using ``setuptools`` (optional).
|
||||
#. Install ``pytest`` using ``pip`` or ``setuptools``.
|
||||
1. Install clean target Python environments.
|
||||
#. Update the project's ``setup.py`` configuration with information on your
|
||||
installed Python environments.
|
||||
#. Run the ``tools/setup_base_environments.py`` script.
|
||||
|
||||
Some older Python environments may have slight issues caused by varying support
|
||||
levels in different used Python packages, but the basic testing functionality
|
||||
|
@ -313,53 +315,151 @@ possible.
|
|||
|
||||
Examples of such issues:
|
||||
|
||||
* Colors not getting displayed on a Windows console terminal, and possibly
|
||||
ANSI color code escape sequences getting displayed instead.
|
||||
* ``pip`` utility not being runnable from the command-line using the ``py -m
|
||||
pip`` syntax for some older versions.
|
||||
* Some specific older Python versions having no SSL support and so must reuse
|
||||
installations downloaded by other Python versions.
|
||||
* Colors not getting displayed on a Windows console terminal, with possibly ANSI
|
||||
color code escape sequences getting displayed instead.
|
||||
* ``pip`` utility can not be run from the command-line using the ``py -m pip``
|
||||
syntax for some older versions. In such cases use the more portable ``py -c
|
||||
"import pip;pip.main()"`` syntax instead.
|
||||
* Some specific older Python versions (e.g. 2.4.3) have no SSL support and so
|
||||
have to reuse installations downloaded by other Python versions.
|
||||
|
||||
|
||||
Running the project tests
|
||||
-------------------------
|
||||
Running the project tests - ``tools/run_all_tests.cmd`` script
|
||||
--------------------------------------------------------------
|
||||
|
||||
``tools/run_all_tests.cmd`` script is a basic *poor man's tox* development
|
||||
script that can be used for running the full project test suite using multiple
|
||||
Python interpreter versions on a Windows development machine. It is intended to
|
||||
be replaced by a more portable ``tox`` based or similar automated testing
|
||||
solution some time in the future.
|
||||
Python interpreter versions on a Windows development machine.
|
||||
|
||||
To run all of the project unit tests with a specific interpreter without
|
||||
additional configuration options run the project's ``setup.py`` script with the
|
||||
'test' parameter and an appropriate Python interpreter. E.g. run any of the
|
||||
following from the top level project folder::
|
||||
Intended to be replaced by a more portable ``tox`` based or similar automated
|
||||
testing solution some time in the future.
|
||||
|
||||
Can be configured by tweaking the script's sources directly:
|
||||
|
||||
* List of target Python environments.
|
||||
* Each target Python environment's invocation command.
|
||||
|
||||
Requires the target Python environment already be set up, and all the packages
|
||||
required for running the project test suite installed. See the `Setting up the
|
||||
development & testing environment`_ section for more detailed information.
|
||||
|
||||
Automatically installs the project in editable mode in all tested Python
|
||||
environments.
|
||||
|
||||
Caveats:
|
||||
|
||||
* This method does not allow you to provide any extra ``pytest`` options when
|
||||
running the project test suite.
|
||||
|
||||
Running the project tests - ``setup.py test`` command
|
||||
-----------------------------------------------------
|
||||
|
||||
Project tests can also be run for a specific Python environment by running the
|
||||
project's ``setup.py`` script in that environment and invoking its ``test``
|
||||
command. E.g. run a command like one of the following ones from the top level
|
||||
project folder::
|
||||
|
||||
py243 setup.py test
|
||||
py27 setup.py test
|
||||
py3 setup.py test
|
||||
|
||||
To have more control over the test suite and be able to specify additional
|
||||
``pytest`` options on the command-line, run it from the top level project folder
|
||||
using ``pytest``, e.g.
|
||||
Note that the ``setup.py`` script always needs to be called from the top level
|
||||
project folder.
|
||||
|
||||
* Using a Python 2.x interpreter::
|
||||
For most Python versions, the target Python environment needs not be set up
|
||||
prior to running this command. Where possible (e.g. not for Python 2.4.x or
|
||||
3.1.x versions), any missing testing requirements will be installed
|
||||
automatically, but not directly into the target environment but in the current
|
||||
folder instead. This functionality should be considered a band-aid though, and
|
||||
setting up the target environment can be better done as described in the
|
||||
`Setting up the development & testing environment`_ section.
|
||||
|
||||
py2 -m pytest
|
||||
The ``setup.py test`` command will build the project if needed and run its
|
||||
complete test suite in the target Python environment. The project does not need
|
||||
to be preinstalled into the target Python environment for this operation to
|
||||
work, and neither will the operation leave it installed.
|
||||
|
||||
* Using a Python 3.x interpreter::
|
||||
Caveats:
|
||||
|
||||
py3 setup.py build & py3 -m pytest build
|
||||
* This method does not allow you to provide any extra ``pytest`` options when
|
||||
running the project test suite.
|
||||
|
||||
In both cases, tests run using Python interpreter version 3.x will be run in the
|
||||
build folder constructed by the ``setup.py`` script running the ``py2to3`` tool
|
||||
on the project's sources.
|
||||
Running the project tests - using ``pytest`` directly
|
||||
-----------------------------------------------------
|
||||
|
||||
You might need to manually remove the build folder in order to have its contents
|
||||
regenerated when wanting to run the test suite using a different Python 3.x
|
||||
interpreter version, as those sources are regenerated based solely on the
|
||||
original & processed source file timestamp information and not the Python
|
||||
version used to process them.
|
||||
To have greater control over the test suite and be able to specify additional
|
||||
``pytest`` options on the command-line, or be able to run the tests on a
|
||||
different project installation (e.g. official release installed directly from
|
||||
PyPI), do the following:
|
||||
|
||||
1. Install the project into the target Python environment.
|
||||
|
||||
* Installing the project can be done by either installing it directly into the
|
||||
target Python environment using one of the following commands (paths used
|
||||
assume the commands are being run from the top level project folder)::
|
||||
|
||||
setup.py install
|
||||
easy_install .
|
||||
pip install .
|
||||
|
||||
Or the project can be installed in editable mode using one of the following
|
||||
commands (so it does not need to be reinstalled after every source code
|
||||
change)::
|
||||
|
||||
setup.py develop
|
||||
easy_install -e .
|
||||
pip install -e .
|
||||
|
||||
* The installation step can be skipped if running Python 2 based project
|
||||
tests, and doing so from the top level project folder.
|
||||
|
||||
2. Run tests using ``pytest``.
|
||||
|
||||
* If using Python 2.x:
|
||||
|
||||
* Run ``pytest`` from the project's top level or ``tests`` folder::
|
||||
|
||||
py2 -m pytest
|
||||
|
||||
* If using Python 3.x:
|
||||
|
||||
* Since the project uses py2to3 source conversion, you need to build the
|
||||
project in order to generate the project's Python 3 sources before they
|
||||
can be tested. If the project has been installed in editable mode, then
|
||||
simply run the following from the top level project folder::
|
||||
|
||||
setup.py build
|
||||
|
||||
and if it has not then rebuild and reinstall it using one of the following
|
||||
commands::
|
||||
|
||||
setup.py develop
|
||||
setup.py install
|
||||
|
||||
Note that you might need to manually remove the build folder in order to
|
||||
have its contents regenerated when wanting to run the test suite using a
|
||||
different Python 3.x interpreter version, as those sources are regenerated
|
||||
based solely on the original & processed source file timestamp information
|
||||
and not the Python version used to process them.
|
||||
|
||||
* Run ``pytest`` from the the project's ``tests`` folder::
|
||||
|
||||
py3 -m pytest
|
||||
|
||||
Each specific test module can also be run directly as a script.
|
||||
|
||||
Notes on the folder from which to run the tests:
|
||||
|
||||
* When running tests from a folder other than the top level project folder, the
|
||||
tested project version needs to first be installed in the used Python
|
||||
environment.
|
||||
* Python 2 tests can be run from the top level project folder, in which case
|
||||
they will work even if the project has not been explicitly installed in the
|
||||
used Python environment. And even if another project version has been
|
||||
installed into the used Python environment, that one will be ignored and the
|
||||
one in the current folder used instead.
|
||||
* Python 3 tests can not be run from the top level project folder or they would
|
||||
attempt and fail to use Python 2 based project sources found in the current
|
||||
folder.
|
||||
|
||||
See the ``pytest`` documentation for a detailed list of available command-line
|
||||
options. Some interesting ones:
|
||||
|
|
|
@ -15,6 +15,9 @@ include TODO.txt
|
|||
include notes/*.rst
|
||||
include notes/*.txt
|
||||
|
||||
# Tests.
|
||||
recursive-include tests *.py
|
||||
|
||||
# Tools.
|
||||
prune tools/__* # local cache folders
|
||||
include tools/*.cmd
|
||||
|
|
15
README.rst
15
README.rst
|
@ -54,6 +54,9 @@ Here are the basic instructions for 3 different installation methods:
|
|||
Installation troubleshooting:
|
||||
-----------------------------
|
||||
|
||||
* Released prior to ``0.7`` have many known installation issues requiring the
|
||||
target Python environment to be manually prepared when using some ancient
|
||||
Python versions, e.g. 2.4, 2.5 or 3.1.
|
||||
* Releases ``0.4.1. jurko 5 < x <= 0.6`` may not be installed using ``pip`` into
|
||||
a Python environment with an already installed ``setuptools`` package older
|
||||
than the version expected by our project. Displayed error message includes
|
||||
|
@ -323,6 +326,9 @@ version 0.7 (development)
|
|||
effectively just leaving the installed ``setuptools`` package with one
|
||||
defective test module, but fully operational at run-time.
|
||||
|
||||
* When installing the project into a Window Python 2.5 environment, you no
|
||||
longer need to manually install a compatible ``colorama`` package versions
|
||||
in order to be able to run the project tests.
|
||||
* Package meta-data may now contain non-ASCII characters on platforms where
|
||||
that is allowed, namely with all Python versions except Python 3.x prior to
|
||||
3.2.2.
|
||||
|
@ -335,12 +341,21 @@ version 0.7 (development)
|
|||
|
||||
* Test suite improvements.
|
||||
|
||||
* Test suite no longer installed together with the project, thus no longer
|
||||
causing confusion by existing in the target Python environment as a global
|
||||
``tests`` package.
|
||||
|
||||
* The tests may now be run from the source archive, and will always run on
|
||||
the suds version found installed in the used Python environment.
|
||||
|
||||
* Refactored the quick & dirty batch script used to run all the project tests
|
||||
in multiple Python environments to remove much code duplication.
|
||||
* Automated project testing in several additional Python environment versions.
|
||||
* Added more detailed XSD modeling tests.
|
||||
* Added tests demonstrating how additional or replacement built-in XSD types
|
||||
can be registered with suds.
|
||||
* All project tests now using Python 2 & 3 compatible source code and so no
|
||||
longer need to be built separately for Python 3.
|
||||
* Added new and updated existing ``suds.cache`` module related tests.
|
||||
* Documented that all ``pytest`` test parametrizations should be prepared so
|
||||
they get ordered the same on all test runs. See ``Project implementation
|
||||
|
|
18
setup.py
18
setup.py
|
@ -533,6 +533,13 @@ def test_requirements():
|
|||
import argparse
|
||||
except ImportError:
|
||||
result.append("argparse")
|
||||
|
||||
# 'six' release 1.5 broke compatibility with Python 2.4.x.
|
||||
if sys.version_info < (2, 5):
|
||||
result.append("six<1.5")
|
||||
else:
|
||||
result.append("six")
|
||||
|
||||
return result
|
||||
|
||||
test_error = None
|
||||
|
@ -575,15 +582,8 @@ else:
|
|||
self.test_suite = True
|
||||
|
||||
def run_tests(self):
|
||||
# Make sure the tests are run on the correct test sources. E.g.
|
||||
# when using Python 3, the tests need to be run in the build folder
|
||||
# where they have been previously processed using py2to3. Running
|
||||
# them directly on the original source tree would fail due to
|
||||
# Python 2/3 source code incompatibility.
|
||||
ei_cmd = self.get_finalized_command("egg_info")
|
||||
build_path = _normalize_path(ei_cmd.egg_base)
|
||||
import pytest
|
||||
sys.exit(pytest.main(["--pyargs", build_path]))
|
||||
sys.exit(pytest.main(["--pyargs", "tests"]))
|
||||
|
||||
distutils_cmdclass["test"] = TestCommand
|
||||
|
||||
|
@ -685,7 +685,7 @@ setup(
|
|||
keywords=["SOAP", "web", "service", "client"],
|
||||
url=project_url,
|
||||
download_url=download_url,
|
||||
packages=recursive_package_list("suds", "tests"),
|
||||
packages=recursive_package_list("suds"),
|
||||
|
||||
author="Jeff Ortel",
|
||||
author_email="jortel@redhat.com",
|
||||
|
|
|
@ -28,4 +28,4 @@ pytest configuration file for the suds test suite.
|
|||
# folder constructed by 'setup.py build' using 'py.test build --markers'. The
|
||||
# plugin will still get loaded correctly when actually running the tests. This
|
||||
# has already been reported as a pytest issue.
|
||||
pytest_plugins = "tests.indirect_parametrize"
|
||||
pytest_plugins = "testutils.indirect_parametrize"
|
||||
|
|
|
@ -27,14 +27,12 @@ specific to a particular web service operation binding.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.argparser
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -148,7 +146,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
</wsdl:service>
|
||||
</wsdl:definitions>
|
||||
""" % (binding_style,))
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
pytest.raises(MyException, client.service.f)
|
||||
pytest.raises(MyException, client.service.f, "x")
|
||||
pytest.raises(MyException, client.service.f, "x", "y")
|
||||
|
@ -198,7 +196,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
</wsdl:service>
|
||||
</wsdl:definitions>
|
||||
""" % (binding_style,))
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
pytest.raises(MyException, client.service.f)
|
||||
pytest.raises(MyException, client.service.f, "x")
|
||||
pytest.raises(MyException, client.service.f, "x", "y")
|
||||
|
@ -607,4 +605,4 @@ def _expect_error(expected_exception, expected_error_text, test_function,
|
|||
else:
|
||||
assert str(e) == expected_error_text
|
||||
finally:
|
||||
del e
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
|
|
@ -22,17 +22,16 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.cache
|
||||
import suds.sax.parser
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
from six import b, next, u
|
||||
|
||||
import datetime
|
||||
import os
|
||||
|
@ -164,16 +163,18 @@ class MockPickleLoad:
|
|||
|
||||
|
||||
# Hardcoded values used in different caching test cases.
|
||||
value_empty = suds.byte_str("")
|
||||
value_f2 = suds.byte_str("fifi2")
|
||||
value_f22 = suds.byte_str("fifi22")
|
||||
value_f3 = suds.byte_str("fifi3")
|
||||
value_p1 = suds.byte_str("pero1")
|
||||
value_p11 = suds.byte_str("pero11")
|
||||
value_p111 = suds.byte_str("pero111")
|
||||
value_p2 = suds.byte_str("pero2")
|
||||
value_p22 = suds.byte_str("pero22")
|
||||
value_unicode = suds.byte_str(u"€ 的 čćžšđČĆŽŠĐ")
|
||||
value_empty = b("")
|
||||
value_f2 = b("fifi2")
|
||||
value_f22 = b("fifi22")
|
||||
value_f3 = b("fifi3")
|
||||
value_p1 = b("pero1")
|
||||
value_p11 = b("pero11")
|
||||
value_p111 = b("pero111")
|
||||
value_p2 = b("pero2")
|
||||
value_p22 = b("pero22")
|
||||
value_unicode = u("\u20AC \u7684 "
|
||||
"\u010D\u0107\u017E\u0161\u0111"
|
||||
"\u010C\u0106\u017D\u0160\u0110").encode("utf-8")
|
||||
|
||||
|
||||
# FileCache item expiration test data - duration, current_time, expect_remove.
|
||||
|
@ -214,8 +215,11 @@ def test_Cache_methods_abstract(monkeypatch, method_name, params):
|
|||
cache = suds.cache.Cache()
|
||||
f = getattr(cache, method_name)
|
||||
e = pytest.raises(Exception, f, *params).value
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "not-implemented"
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "not-implemented"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestDefaultFileCacheLocation:
|
||||
|
@ -313,7 +317,7 @@ check_cache_folder(True, 1, "final caches with default location")
|
|||
"fake_cache_folder": fake_cache_folder})
|
||||
|
||||
assert not os.path.exists(cache_folder)
|
||||
tests.run_test_process(test_file)
|
||||
testutils.run_test_process(test_file)
|
||||
|
||||
@pytest.mark.parametrize("removal_enabled", (True, False))
|
||||
def test_remove_on_exit(self, tmpdir, removal_enabled):
|
||||
|
@ -363,14 +367,14 @@ if not os.path.isdir(cache_folder):
|
|||
""" % {"cache_folder": cache_folder, "removal_enabled": removal_enabled})
|
||||
|
||||
assert not os.path.exists(cache_folder)
|
||||
tests.run_test_process(test_file)
|
||||
testutils.run_test_process(test_file)
|
||||
if removal_enabled:
|
||||
assert not os.path.exists(cache_folder)
|
||||
else:
|
||||
assert os.path.isdir(cache_folder)
|
||||
|
||||
|
||||
# TODO: DocumentCache class interface seems silly. Its get() operation returns
|
||||
#TODO: DocumentCache class interface seems silly. Its get() operation returns
|
||||
# an XML document while its put() operation takes an XML element. The put()
|
||||
# operation also silently ignores passed data of incorrect type.
|
||||
class TestDocumentCache:
|
||||
|
@ -392,7 +396,7 @@ class TestDocumentCache:
|
|||
Constructed content may be parametrized with the given element name.
|
||||
|
||||
"""
|
||||
# TODO: Update the tests in this group to no longer depend on the exact
|
||||
#TODO: Update the tests in this group to no longer depend on the exact
|
||||
# input XML data formatting. They currently expect it to be formatted
|
||||
# exactly as what gets read back from their DocumentCache.
|
||||
content = suds.byte_str("""\
|
||||
|
@ -885,13 +889,19 @@ def test_NoCache(monkeypatch):
|
|||
cache.put("id", "something")
|
||||
assert cache.get("id") == None
|
||||
|
||||
# TODO: It should not be an error to call clear() or purge() on a NoCache
|
||||
#TODO: It should not be an error to call clear() or purge() on a NoCache
|
||||
# instance.
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(Exception, cache.purge, "id").value
|
||||
assert str(e) == "not-implemented"
|
||||
try:
|
||||
assert str(e) == "not-implemented"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
e = pytest.raises(Exception, cache.clear).value
|
||||
assert str(e) == "not-implemented"
|
||||
try:
|
||||
assert str(e) == "not-implemented"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestObjectCache:
|
||||
|
@ -1015,7 +1025,7 @@ def _assert_empty_cache_folder(folder, expected=True):
|
|||
assert os.path.isdir(folder)
|
||||
def walk_error(error):
|
||||
pytest.fail("Error walking through cache folder content.")
|
||||
root, folders, files = os.walk(folder, onerror=walk_error).next()
|
||||
root, folders, files = next(os.walk(folder, onerror=walk_error))
|
||||
assert root == folder
|
||||
empty = len(folders) == 0 and len(files) == 1 and files[0] == 'version'
|
||||
if expected:
|
||||
|
|
|
@ -22,21 +22,19 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.cache
|
||||
import suds.store
|
||||
import suds.transport
|
||||
import suds.transport.https
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
|
||||
import httplib
|
||||
from six import iteritems, itervalues, next
|
||||
from six.moves import http_client
|
||||
|
||||
|
||||
class MyException(Exception):
|
||||
|
@ -147,7 +145,7 @@ class MockTransport(suds.transport.Transport):
|
|||
self.mock_log.append(("send", [request.url, request.message]))
|
||||
if not self.mock_send_data:
|
||||
pytest.fail("Unexpected MockTransport.send() operation call.")
|
||||
status = httplib.OK
|
||||
status = http_client.OK
|
||||
headers = {}
|
||||
data = self.__next_operation_result(self.mock_send_data)
|
||||
return suds.transport.Reply(status, headers, data)
|
||||
|
@ -169,7 +167,7 @@ class MockTransport(suds.transport.Transport):
|
|||
#TODO: Once a WSDL import bug illustrated by test_WSDL_import() is fixed, this
|
||||
# test data may be simplified to just:
|
||||
# > wsdl_target_namespace = "bingo-bongo"
|
||||
# > wsdl = tests.wsdl("", wsdl_target_namespace=wsdl_target_namespace)
|
||||
# > wsdl = testutils.wsdl("", wsdl_target_namespace=wsdl_target_namespace)
|
||||
# > wsdl_wrapper = suds.byte_str("""\
|
||||
# > <?xml version='1.0' encoding='UTF-8'?>
|
||||
# > <definitions targetNamespace="%(tns)s"
|
||||
|
@ -256,7 +254,7 @@ class TestCacheStoreTransportUsage:
|
|||
cache=cache, documentStore=store1, transport=MockTransport())
|
||||
assert store1.mock_log == ["suds://wsdl", "suds://wsdl_imported"]
|
||||
assert len(cache.mock_data) == 1
|
||||
wsdl_object_id, wsdl_object = cache.mock_data.items()[0]
|
||||
wsdl_object_id, wsdl_object = next(iteritems(cache.mock_data))
|
||||
assert wsdl_object.__class__ is suds.wsdl.Definitions
|
||||
|
||||
# Reuse from cache.
|
||||
|
@ -270,7 +268,7 @@ class TestCacheStoreTransportUsage:
|
|||
def test_avoid_external_XSD_fetching(self):
|
||||
# Prepare document content.
|
||||
xsd_target_namespace = "balancana"
|
||||
wsdl = tests.wsdl("""\
|
||||
wsdl = testutils.wsdl("""\
|
||||
<xsd:import schemaLocation="suds://imported_xsd"/>
|
||||
<xsd:include schemaLocation="suds://included_xsd"/>""",
|
||||
xsd_target_namespace=xsd_target_namespace)
|
||||
|
@ -291,7 +289,7 @@ class TestCacheStoreTransportUsage:
|
|||
assert store1.mock_log == ["suds://wsdl", "suds://imported_xsd",
|
||||
"suds://included_xsd"]
|
||||
assert len(cache.mock_data) == 1
|
||||
wsdl_object_id, wsdl_object = cache.mock_data.items()[0]
|
||||
wsdl_object_id, wsdl_object = next(iteritems(cache.mock_data))
|
||||
assert wsdl_object.__class__ is suds.wsdl.Definitions
|
||||
|
||||
# Reuse from cache.
|
||||
|
@ -393,7 +391,7 @@ class TestCacheStoreTransportUsage:
|
|||
# Add to cache, making sure the WSDL schema is read from the document
|
||||
# store and not fetched using the client's registered transport.
|
||||
cache = MockCache()
|
||||
store1 = MockDocumentStore(umpala=tests.wsdl(""))
|
||||
store1 = MockDocumentStore(umpala=testutils.wsdl(""))
|
||||
c1 = suds.client.Client("suds://umpala", cachingpolicy=caching_policy,
|
||||
cache=cache, documentStore=store1, transport=MockTransport())
|
||||
assert [x for x, y in cache.mock_log] == ["get", "put"]
|
||||
|
@ -402,12 +400,12 @@ class TestCacheStoreTransportUsage:
|
|||
assert len(cache.mock_data) == 1
|
||||
if caching_policy == 0:
|
||||
# Cache contains SAX XML documents.
|
||||
wsdl_document = cache.mock_data.values()[0]
|
||||
wsdl_document = next(itervalues(cache.mock_data))
|
||||
assert wsdl_document.__class__ is suds.sax.document.Document
|
||||
wsdl_cached_root = wsdl_document.root()
|
||||
else:
|
||||
# Cache contains complete suds WSDL objects.
|
||||
wsdl = cache.mock_data.values()[0]
|
||||
wsdl = next(itervalues(cache.mock_data))
|
||||
assert wsdl.__class__ is suds.wsdl.Definitions
|
||||
wsdl_cached_root = wsdl.root
|
||||
assert c1.wsdl.root is wsdl_cached_root
|
||||
|
@ -442,7 +440,7 @@ class TestCacheStoreTransportUsage:
|
|||
"""
|
||||
# Prepare document content.
|
||||
xsd_target_namespace = "my xsd namespace"
|
||||
wsdl = tests.wsdl('<xsd:%s schemaLocation="suds://external"/>' % (
|
||||
wsdl = testutils.wsdl('<xsd:%s schemaLocation="suds://external"/>' % (
|
||||
external_reference_tag,),
|
||||
xsd_target_namespace=xsd_target_namespace)
|
||||
external_schema = suds.byte_str("""\
|
||||
|
@ -554,8 +552,11 @@ class TestCacheUsage:
|
|||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(AttributeError, suds.client.Client,
|
||||
"suds://some_URL", cache=cache).value
|
||||
expected_error = '"cache" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.cache.Cache,)
|
||||
try:
|
||||
expected_error = '"cache" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.cache.Cache,)
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestStoreUsage:
|
||||
|
@ -566,15 +567,18 @@ class TestStoreUsage:
|
|||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(AttributeError, suds.client.Client,
|
||||
"suds://some_URL", documentStore=store, cache=None).value
|
||||
expected_error = '"documentStore" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.store.DocumentStore,)
|
||||
try:
|
||||
expected_error = '"documentStore" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.store.DocumentStore,)
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestTransportUsage:
|
||||
"""suds.client.Client transport component usage tests."""
|
||||
|
||||
def test_default_transport(self):
|
||||
client = tests.client_from_wsdl(tests.wsdl(""))
|
||||
client = testutils.client_from_wsdl(testutils.wsdl(""))
|
||||
expected = suds.transport.https.HttpAuthenticated
|
||||
assert client.options.transport.__class__ is expected
|
||||
|
||||
|
@ -586,12 +590,15 @@ class TestTransportUsage:
|
|||
transport = MockTransport(open_data=exception)
|
||||
e_info = pytest.raises(exception.__class__, suds.client.Client, "url",
|
||||
cache=None, transport=transport)
|
||||
assert e_info.value is exception
|
||||
try:
|
||||
assert e_info.value is exception
|
||||
finally:
|
||||
del e_info # explicitly break circular reference chain in Python 3
|
||||
|
||||
def test_error_on_send__non_transport(self):
|
||||
e = MyException()
|
||||
t = MockTransport(send_data=e)
|
||||
store = MockDocumentStore(wsdl=tests.wsdl("", operation_name="g"))
|
||||
store = MockDocumentStore(wsdl=testutils.wsdl("", operation_name="g"))
|
||||
client = suds.client.Client("suds://wsdl", documentStore=store,
|
||||
cache=None, transport=t)
|
||||
assert pytest.raises(MyException, client.service.g).value is e
|
||||
|
@ -610,24 +617,27 @@ class TestTransportUsage:
|
|||
def test_error_on_send__transport(self, monkeypatch):
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
t = MockTransport(send_data=suds.transport.TransportError("huku", 666))
|
||||
store = MockDocumentStore(wsdl=tests.wsdl("", operation_name="g"))
|
||||
store = MockDocumentStore(wsdl=testutils.wsdl("", operation_name="g"))
|
||||
client = suds.client.Client("suds://wsdl", documentStore=store,
|
||||
cache=None, transport=t)
|
||||
e = pytest.raises(Exception, client.service.g).value
|
||||
assert e.__class__ is Exception
|
||||
assert e.args == ((666, "huku"),)
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert e.args == ((666, "huku"),)
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
def test_nosend_should_avoid_transport_sends(self):
|
||||
wsdl = tests.wsdl("")
|
||||
wsdl = testutils.wsdl("")
|
||||
t = MockTransport()
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, transport=t)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, transport=t)
|
||||
client.service.f()
|
||||
|
||||
def test_operation_request_and_reply(self):
|
||||
xsd_content = '<xsd:element name="Data" type="xsd:string"/>'
|
||||
web_service_URL = "Great minds think alike"
|
||||
xsd_target_namespace = "omicron psi"
|
||||
wsdl = tests.wsdl(suds.byte_str(xsd_content), operation_name="pi",
|
||||
wsdl = testutils.wsdl(suds.byte_str(xsd_content), operation_name="pi",
|
||||
xsd_target_namespace=xsd_target_namespace, input="Data",
|
||||
output="Data", web_service_URL=web_service_URL)
|
||||
test_input_data = "Riff-raff"
|
||||
|
@ -657,13 +667,16 @@ class TestTransportUsage:
|
|||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(AttributeError, suds.client.Client,
|
||||
"suds://some_URL", transport=transport, cache=None).value
|
||||
expected_error = '"transport" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.transport.Transport,)
|
||||
try:
|
||||
expected_error = '"transport" must be: (%r,)'
|
||||
assert str(e) == expected_error % (suds.transport.Transport,)
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
@pytest.mark.parametrize("url", test_URL_data)
|
||||
def test_WSDL_transport(self, url):
|
||||
store = MockDocumentStore()
|
||||
t = MockTransport(open_data=tests.wsdl(""))
|
||||
t = MockTransport(open_data=testutils.wsdl(""))
|
||||
suds.client.Client(url, cache=None, documentStore=store, transport=t)
|
||||
assert t.mock_log == [("open", [url])]
|
||||
|
||||
|
@ -682,7 +695,7 @@ class TestTransportUsage:
|
|||
def test_external_XSD_transport(self, url, external_reference_tag):
|
||||
xsd_content = '<xsd:%(tag)s schemaLocation="%(url)s"/>' % dict(
|
||||
tag=external_reference_tag, url=url)
|
||||
store = MockDocumentStore(wsdl=tests.wsdl(xsd_content))
|
||||
store = MockDocumentStore(wsdl=testutils.wsdl(xsd_content))
|
||||
t = MockTransport(open_data=suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<schema xmlns="http://www.w3.org/2001/XMLSchema"/>
|
||||
|
@ -695,7 +708,7 @@ class TestTransportUsage:
|
|||
@pytest.mark.xfail(reason="WSDL import buggy")
|
||||
def test_WSDL_import():
|
||||
wsdl_target_namespace = "bingo-bongo"
|
||||
wsdl = tests.wsdl("", wsdl_target_namespace=wsdl_target_namespace)
|
||||
wsdl = testutils.wsdl("", wsdl_target_namespace=wsdl_target_namespace)
|
||||
wsdl_wrapper = suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<definitions targetNamespace="%(tns)s"
|
||||
|
|
|
@ -23,10 +23,11 @@ CompareSAX testing utility unit tests.
|
|||
import suds
|
||||
import suds.sax.document
|
||||
import suds.sax.parser
|
||||
from tests.assertion import assert_no_output
|
||||
from tests.compare_sax import CompareSAX
|
||||
from testutils.assertion import assert_no_output
|
||||
from testutils.compare_sax import CompareSAX
|
||||
|
||||
import pytest
|
||||
from six import text_type, u
|
||||
|
||||
import xml.sax
|
||||
|
||||
|
@ -74,14 +75,14 @@ class TestMatched:
|
|||
('<a xmlns="one"/>', '<ns:a xmlns:ns="one"/>'),
|
||||
('<ns1:b xmlns:ns1="two"/>', '<ns2:b xmlns:ns2="two"/>'),
|
||||
# Numeric unicode character references.
|
||||
(u"<a>☆</a>", "<a>☆</a>")))
|
||||
(u("<a>\u2606</a>"), "<a>&#%d;</a>" % (0x2606,))))
|
||||
def test_data2data(self, data1, data2, capsys):
|
||||
CompareSAX.data2data(data1, data2)
|
||||
assert_no_output(capsys)
|
||||
|
||||
@skip_test_if_CompareSAX_assertions_disabled
|
||||
@pytest.mark.parametrize("type1", (suds.byte_str, unicode))
|
||||
@pytest.mark.parametrize("type2", (suds.byte_str, unicode))
|
||||
@pytest.mark.parametrize("type1", (suds.byte_str, text_type))
|
||||
@pytest.mark.parametrize("type2", (suds.byte_str, text_type))
|
||||
def test_string_input_types(self, type1, type2, capsys):
|
||||
xml = "<a/>"
|
||||
CompareSAX.data2data(type1(xml), type2(xml))
|
||||
|
@ -90,7 +91,7 @@ class TestMatched:
|
|||
@skip_test_if_CompareSAX_assertions_disabled
|
||||
def test_xml_encoding(self, capsys):
|
||||
"""Test that the encoding listed in the XML declaration is honored."""
|
||||
xml_format = u'<?xml version="1.0" encoding="%s"?><a>Ø</a>'
|
||||
xml_format = u('<?xml version="1.0" encoding="%s"?><a>\u00D8</a>')
|
||||
data1 = (xml_format % ("UTF-8",)).encode('utf-8')
|
||||
data2 = (xml_format % ("latin1",)).encode('latin1')
|
||||
CompareSAX.data2data(data1, data2)
|
||||
|
@ -103,50 +104,50 @@ class TestMismatched:
|
|||
@skip_test_if_CompareSAX_assertions_disabled
|
||||
@pytest.mark.parametrize(("data1", "data2", "expected_context"), (
|
||||
# Different element namespaces.
|
||||
("<a/>", '<a xmlns="x"/>', u"data2data.<a>.namespace"),
|
||||
('<a xmlns="1"/>', '<a xmlns="2"/>', u"data2data.<a>.namespace"),
|
||||
("<a/>", '<a xmlns="x"/>', "data2data.<a>.namespace"),
|
||||
('<a xmlns="1"/>', '<a xmlns="2"/>', "data2data.<a>.namespace"),
|
||||
('<r><a xmlns="1"/></r>', '<r><a xmlns="2"/></r>',
|
||||
u"data2data.<r>.<a>.namespace"),
|
||||
"data2data.<r>.<a>.namespace"),
|
||||
('<r><tag><a xmlns="1"/></tag><y/></r>',
|
||||
'<r><tag><a xmlns="2"/></tag><y/></r>',
|
||||
u"data2data.<r>.<tag(1/2)>.<a>.namespace"),
|
||||
"data2data.<r>.<tag(1/2)>.<a>.namespace"),
|
||||
# Different textual content in text only nodes.
|
||||
("<a>one</a>", "<a>two</a>", u"data2data.<a>.text"),
|
||||
("<a>x</a>", "<a>x </a>", u"data2data.<a>.text"),
|
||||
("<a>x</a>", "<a>x </a>", u"data2data.<a>.text"),
|
||||
("<a>x </a>", "<a>x </a>", u"data2data.<a>.text"),
|
||||
("<a> x</a>", "<a>x</a>", u"data2data.<a>.text"),
|
||||
("<a> x</a>", "<a>x</a>", u"data2data.<a>.text"),
|
||||
("<a> x</a>", "<a> x</a>", u"data2data.<a>.text"),
|
||||
("<a>one</a>", "<a>two</a>", "data2data.<a>.text"),
|
||||
("<a>x</a>", "<a>x </a>", "data2data.<a>.text"),
|
||||
("<a>x</a>", "<a>x </a>", "data2data.<a>.text"),
|
||||
("<a>x </a>", "<a>x </a>", "data2data.<a>.text"),
|
||||
("<a> x</a>", "<a>x</a>", "data2data.<a>.text"),
|
||||
("<a> x</a>", "<a>x</a>", "data2data.<a>.text"),
|
||||
("<a> x</a>", "<a> x</a>", "data2data.<a>.text"),
|
||||
("<a><b><c>x</c><c2/></b></a>", "<a><b><c>X</c><c2/></b></a>",
|
||||
u"data2data.<a>.<b>.<c(1/2)>.text"),
|
||||
"data2data.<a>.<b>.<c(1/2)>.text"),
|
||||
("<a><b><c>x</c><d>y</d></b></a>", "<a><b><c>x</c><d>Y</d></b></a>",
|
||||
u"data2data.<a>.<b>.<d(2/2)>.text"),
|
||||
"data2data.<a>.<b>.<d(2/2)>.text"),
|
||||
# Different textual content in mixed content nodes with children.
|
||||
("<a>42<b/><b/>42</a>", "<a>42<b/> <b/>42</a>", u"data2data.<a>.text"),
|
||||
("<a>42<b/><b/>42</a>", "<a>42<b/> <b/>42</a>", "data2data.<a>.text"),
|
||||
# Differently named elements.
|
||||
("<a/>", "<b/>", u"data2data.<a/b>"),
|
||||
("<a><b/></a>", "<a><c/></a>", u"data2data.<a>.<b/c>"),
|
||||
("<a><b/><x/></a>", "<a><c/><x/></a>", u"data2data.<a>.<b/c(1/2)>"),
|
||||
("<a><x/><b/></a>", "<a><x/><c/></a>", u"data2data.<a>.<b/c(2/2)>"),
|
||||
("<a/>", "<b/>", "data2data.<a/b>"),
|
||||
("<a><b/></a>", "<a><c/></a>", "data2data.<a>.<b/c>"),
|
||||
("<a><b/><x/></a>", "<a><c/><x/></a>", "data2data.<a>.<b/c(1/2)>"),
|
||||
("<a><x/><b/></a>", "<a><x/><c/></a>", "data2data.<a>.<b/c(2/2)>"),
|
||||
("<a><b><c/></b></a>", "<a><b><d/></b></a>",
|
||||
u"data2data.<a>.<b>.<c/d>"),
|
||||
"data2data.<a>.<b>.<c/d>"),
|
||||
("<a><b><y1/><y2/><c/></b><x/></a>",
|
||||
"<a><b><y1/><y2/><d/></b><x/></a>",
|
||||
u"data2data.<a>.<b(1/2)>.<c/d(3/3)>"),
|
||||
"data2data.<a>.<b(1/2)>.<c/d(3/3)>"),
|
||||
# Extra/missing non-root element.
|
||||
("<a><b/></a>", "<a/>", u"data2data.<a>"),
|
||||
("<a/>", "<a><b/></a>", u"data2data.<a>"),
|
||||
("<a><x/><b/></a>", "<a><b/></a>", u"data2data.<a>"),
|
||||
("<a><b/><x/></a>", "<a><b/></a>", u"data2data.<a>"),
|
||||
("<a><b/></a>", "<a><x/><b/></a>", u"data2data.<a>"),
|
||||
("<a><b/></a>", "<a><b/><x/></a>", u"data2data.<a>"),
|
||||
("<a><b/></a>", "<a/>", "data2data.<a>"),
|
||||
("<a/>", "<a><b/></a>", "data2data.<a>"),
|
||||
("<a><x/><b/></a>", "<a><b/></a>", "data2data.<a>"),
|
||||
("<a><b/><x/></a>", "<a><b/></a>", "data2data.<a>"),
|
||||
("<a><b/></a>", "<a><x/><b/></a>", "data2data.<a>"),
|
||||
("<a><b/></a>", "<a><b/><x/></a>", "data2data.<a>"),
|
||||
# Multiple differences.
|
||||
("<a><b/></a>", "<c><d/></c>", u"data2data.<a/c>"),
|
||||
("<a><b/></a>", '<a xmlns="o"><c/></a>', u"data2data.<a>.namespace"),
|
||||
("<r><a><b/></a></r>", "<r><c><d/></c></r>", u"data2data.<r>.<a/c>"),
|
||||
("<a><b/></a>", "<c><d/></c>", "data2data.<a/c>"),
|
||||
("<a><b/></a>", '<a xmlns="o"><c/></a>', "data2data.<a>.namespace"),
|
||||
("<r><a><b/></a></r>", "<r><c><d/></c></r>", "data2data.<r>.<a/c>"),
|
||||
("<r><a><b/></a></r>", '<r><a xmlns="o"><c/></a></r>',
|
||||
u"data2data.<r>.<a>.namespace")))
|
||||
"data2data.<r>.<a>.namespace")))
|
||||
def test_data2data(self, data1, data2, expected_context, capsys):
|
||||
pytest.raises(AssertionError, CompareSAX.data2data, data1, data2)
|
||||
_assert_context_output(capsys, expected_context)
|
||||
|
@ -237,4 +238,4 @@ def _assert_context_output(capsys, context):
|
|||
"""
|
||||
out, err = capsys.readouterr()
|
||||
assert not out
|
||||
assert err == u"Failed SAX XML comparison context:\n %s\n" % (context,)
|
||||
assert err == "Failed SAX XML comparison context:\n %s\n" % (context,)
|
||||
|
|
|
@ -21,13 +21,11 @@ Implemented using the 'pytest' testing framework.
|
|||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
import testutils
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
from suds.sax.date import (FixedOffsetTimezone, Date, DateTime, Time,
|
||||
UtcTimezone)
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
|
||||
|
|
|
@ -23,9 +23,8 @@ Implemented using the 'pytest' testing framework.
|
|||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
import testutils
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.store
|
||||
|
|
|
@ -35,13 +35,11 @@ operation's input parameters correctly.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -246,7 +244,7 @@ class TestUnsupportedParameterDefinitions:
|
|||
else:
|
||||
assert str(e) == expected_error_text
|
||||
finally:
|
||||
del e
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
def init_function_params(self, params, **kwargs):
|
||||
"""
|
||||
|
@ -265,8 +263,8 @@ class TestUnsupportedParameterDefinitions:
|
|||
"""
|
||||
input = '<xsd:element name="Wrapper">%s</xsd:element>' % (params,)
|
||||
assert not hasattr(self, "service")
|
||||
wsdl = tests.wsdl(input, input="Wrapper", **kwargs)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True)
|
||||
wsdl = testutils.wsdl(input, input="Wrapper", **kwargs)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True)
|
||||
self.service = client.service
|
||||
|
||||
@pytest.mark.parametrize("test_args_required", (
|
||||
|
@ -383,7 +381,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
</wsdl:port>
|
||||
</wsdl:service>
|
||||
</wsdl:definitions>""" % (part_name,))
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True)
|
||||
|
||||
# Collect references to required WSDL model content.
|
||||
method = client.wsdl.services[0].ports[0].methods["f"]
|
||||
|
@ -405,7 +403,7 @@ def test_explicitly_wrapped_parameter(part_name):
|
|||
"""
|
||||
input_schema = sequence_choice_with_element_and_two_element_sequence.xsd
|
||||
wsdl = _unwrappable_wsdl(part_name, input_schema)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, unwrap=False)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, unwrap=False)
|
||||
|
||||
# Collect references to required WSDL model content.
|
||||
method = client.wsdl.services[0].ports[0].methods["f"]
|
||||
|
@ -473,7 +471,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
</wsdl:service>
|
||||
</wsdl:definitions>""")
|
||||
wsdl = suds.byte_str("".join(wsdl))
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True)
|
||||
|
||||
# Collect references to required WSDL model content.
|
||||
method = client.wsdl.services[0].ports[0].methods["f"]
|
||||
|
@ -505,7 +503,7 @@ def test_unwrapped_parameter(xsd_type):
|
|||
"""Test recognizing unwrapped web service operation input structures."""
|
||||
input_schema = sequence_choice_with_element_and_two_element_sequence.xsd
|
||||
wsdl = _unwrappable_wsdl("part_name", input_schema)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True)
|
||||
|
||||
# Collect references to required WSDL model content.
|
||||
method = client.wsdl.services[0].ports[0].methods["f"]
|
||||
|
@ -530,7 +528,7 @@ def test_unwrapped_parameter_part_name(part_name):
|
|||
"""
|
||||
input_schema = sequence_choice_with_element_and_two_element_sequence.xsd
|
||||
wsdl = _unwrappable_wsdl(part_name, input_schema)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True)
|
||||
|
||||
# Collect references to required WSDL model content.
|
||||
method = client.wsdl.services[0].ports[0].methods["f"]
|
||||
|
|
|
@ -22,15 +22,13 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.options
|
||||
import suds.reader
|
||||
import tests
|
||||
|
||||
|
||||
class TestCacheItemNameMangling:
|
||||
|
@ -70,7 +68,7 @@ assert mangled == '%(expected)s'
|
|||
""" % {"expected": expected,
|
||||
"test_item_name": test_item_name,
|
||||
"test_item_suffix": test_item_suffix})
|
||||
tests.run_test_process(test_file)
|
||||
testutils.run_test_process(test_file)
|
||||
|
||||
def test_repeatable__different_readers(self):
|
||||
test_item_name = "R2D2"
|
||||
|
|
|
@ -22,49 +22,48 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
from six import itervalues, next, u
|
||||
from six.moves import http_client
|
||||
|
||||
import httplib
|
||||
import xml.sax
|
||||
|
||||
|
||||
def test_ACCEPTED_and_NO_CONTENT_status_reported_as_None_with_faults():
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
def f(reply, status):
|
||||
inject = {"reply": suds.byte_str(reply), "status": status}
|
||||
return client.service.f(__inject=inject)
|
||||
assert f("", None) is None
|
||||
pytest.raises(Exception, f, "", httplib.INTERNAL_SERVER_ERROR)
|
||||
assert f("", httplib.ACCEPTED) is None
|
||||
assert f("", httplib.NO_CONTENT) is None
|
||||
assert f("bla-bla", httplib.ACCEPTED) is None
|
||||
assert f("bla-bla", httplib.NO_CONTENT) is None
|
||||
pytest.raises(Exception, f, "", http_client.INTERNAL_SERVER_ERROR)
|
||||
assert f("", http_client.ACCEPTED) is None
|
||||
assert f("", http_client.NO_CONTENT) is None
|
||||
assert f("bla-bla", http_client.ACCEPTED) is None
|
||||
assert f("bla-bla", http_client.NO_CONTENT) is None
|
||||
|
||||
|
||||
def test_ACCEPTED_and_NO_CONTENT_status_reported_as_None_without_faults():
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
def f(reply, status):
|
||||
inject = {"reply": suds.byte_str(reply), "status": status}
|
||||
return client.service.f(__inject=inject)
|
||||
assert f("", None) is not None
|
||||
assert f("", httplib.INTERNAL_SERVER_ERROR) is not None
|
||||
assert f("", httplib.ACCEPTED) is None
|
||||
assert f("", httplib.NO_CONTENT) is None
|
||||
assert f("bla-bla", httplib.ACCEPTED) is None
|
||||
assert f("bla-bla", httplib.NO_CONTENT) is None
|
||||
assert f("", http_client.INTERNAL_SERVER_ERROR) is not None
|
||||
assert f("", http_client.ACCEPTED) is None
|
||||
assert f("", http_client.NO_CONTENT) is None
|
||||
assert f("bla-bla", http_client.ACCEPTED) is None
|
||||
assert f("bla-bla", http_client.NO_CONTENT) is None
|
||||
|
||||
|
||||
def test_badly_formed_reply_XML():
|
||||
for faults in (True, False):
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=faults)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=faults)
|
||||
pytest.raises(xml.sax.SAXParseException, client.service.f,
|
||||
__inject={"reply": suds.byte_str("bad food")})
|
||||
|
||||
|
@ -74,7 +73,7 @@ def test_badly_formed_reply_XML():
|
|||
# restriction's underlying data type.
|
||||
@pytest.mark.xfail
|
||||
def test_restriction_data_types():
|
||||
client_unnamed = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_unnamed = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Elemento">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:int">
|
||||
|
@ -85,7 +84,7 @@ def test_restriction_data_types():
|
|||
</xsd:simpleType>
|
||||
</xsd:element>""", output="Elemento"))
|
||||
|
||||
client_named = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_named = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:simpleType name="MyType">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:enumeration value="1"/>
|
||||
|
@ -95,7 +94,7 @@ def test_restriction_data_types():
|
|||
</xsd:simpleType>
|
||||
<xsd:element name="Elemento" type="ns:MyType"/>""", output="Elemento"))
|
||||
|
||||
client_twice_restricted = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_twice_restricted = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:simpleType name="MyTypeGeneric">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:enumeration value="1"/>
|
||||
|
@ -127,7 +126,7 @@ def test_restriction_data_types():
|
|||
|
||||
|
||||
def test_disabling_automated_simple_interface_unwrapping():
|
||||
client = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -155,33 +154,35 @@ def test_disabling_automated_simple_interface_unwrapping():
|
|||
|
||||
|
||||
def test_empty_reply():
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
def f(status=None, description=None):
|
||||
inject = dict(reply=suds.byte_str(), status=status,
|
||||
description=description)
|
||||
return client.service.f(__inject=inject)
|
||||
status, reason = f()
|
||||
assert status == httplib.OK
|
||||
assert status == http_client.OK
|
||||
assert reason is None
|
||||
status, reason = f(httplib.OK)
|
||||
assert status == httplib.OK
|
||||
status, reason = f(http_client.OK)
|
||||
assert status == http_client.OK
|
||||
assert reason is None
|
||||
status, reason = f(httplib.INTERNAL_SERVER_ERROR)
|
||||
assert status == httplib.INTERNAL_SERVER_ERROR
|
||||
status, reason = f(http_client.INTERNAL_SERVER_ERROR)
|
||||
assert status == http_client.INTERNAL_SERVER_ERROR
|
||||
assert reason == "injected reply"
|
||||
status, reason = f(httplib.FORBIDDEN)
|
||||
assert status == httplib.FORBIDDEN
|
||||
status, reason = f(http_client.FORBIDDEN)
|
||||
assert status == http_client.FORBIDDEN
|
||||
assert reason == "injected reply"
|
||||
status, reason = f(httplib.FORBIDDEN, "kwack")
|
||||
assert status == httplib.FORBIDDEN
|
||||
status, reason = f(http_client.FORBIDDEN, "kwack")
|
||||
assert status == http_client.FORBIDDEN
|
||||
assert reason == "kwack"
|
||||
|
||||
|
||||
def test_fault_reply_with_unicode_faultstring(monkeypatch):
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
|
||||
unicode_string = u"€ Jurko Gospodnetić ČĆŽŠĐčćžšđ"
|
||||
fault_xml = suds.byte_str(u"""\
|
||||
unicode_string = u("\u20AC Jurko Gospodneti\u0107 "
|
||||
"\u010C\u0106\u017D\u0160\u0110"
|
||||
"\u010D\u0107\u017E\u0161\u0111")
|
||||
fault_xml = suds.byte_str(u("""\
|
||||
<?xml version="1.0"?>
|
||||
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<env:Body>
|
||||
|
@ -191,18 +192,21 @@ def test_fault_reply_with_unicode_faultstring(monkeypatch):
|
|||
</env:Fault>
|
||||
</env:Body>
|
||||
</env:Envelope>
|
||||
""" % (unicode_string,))
|
||||
""") % (unicode_string,))
|
||||
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
inject = dict(reply=fault_xml, status=httplib.INTERNAL_SERVER_ERROR)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
inject = dict(reply=fault_xml, status=http_client.INTERNAL_SERVER_ERROR)
|
||||
e = pytest.raises(suds.WebFault, client.service.f, __inject=inject).value
|
||||
assert e.fault.faultstring == unicode_string
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
try:
|
||||
assert e.fault.faultstring == unicode_string
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
status, fault = client.service.f(__inject=dict(reply=fault_xml,
|
||||
status=httplib.INTERNAL_SERVER_ERROR))
|
||||
assert status == httplib.INTERNAL_SERVER_ERROR
|
||||
status=http_client.INTERNAL_SERVER_ERROR))
|
||||
assert status == http_client.INTERNAL_SERVER_ERROR
|
||||
assert fault.faultstring == unicode_string
|
||||
|
||||
|
||||
|
@ -223,14 +227,17 @@ def test_invalid_fault_namespace(monkeypatch):
|
|||
</env:Body>
|
||||
</env:Envelope>
|
||||
""")
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
inject = dict(reply=fault_xml, status=httplib.OK)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
inject = dict(reply=fault_xml, status=http_client.OK)
|
||||
e = pytest.raises(Exception, client.service.f, __inject=inject).value
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "<faultcode/> not mapped to message part"
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "<faultcode/> not mapped to message part"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
for http_status in (httplib.INTERNAL_SERVER_ERROR,
|
||||
httplib.PAYMENT_REQUIRED):
|
||||
for http_status in (http_client.INTERNAL_SERVER_ERROR,
|
||||
http_client.PAYMENT_REQUIRED):
|
||||
status, reason = client.service.f(__inject=dict(reply=fault_xml,
|
||||
status=http_status, description="trla baba lan"))
|
||||
assert status == http_status
|
||||
|
@ -243,7 +250,7 @@ def test_missing_wrapper_response():
|
|||
interpreting received SOAP Response XML.
|
||||
|
||||
"""
|
||||
client = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -266,88 +273,100 @@ def test_missing_wrapper_response():
|
|||
def test_reply_error_with_detail_with_fault(monkeypatch):
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
|
||||
for http_status in (httplib.OK, httplib.INTERNAL_SERVER_ERROR):
|
||||
for http_status in (http_client.OK, http_client.INTERNAL_SERVER_ERROR):
|
||||
inject = dict(reply=_fault_reply__with_detail, status=http_status)
|
||||
e = pytest.raises(suds.WebFault, client.service.f, __inject=inject)
|
||||
e = e.value
|
||||
_test_fault(e.fault, True)
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
assert str(e) == "Server raised fault: 'Dummy error.'"
|
||||
try:
|
||||
e = e.value
|
||||
_test_fault(e.fault, True)
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
assert str(e) == "Server raised fault: 'Dummy error.'"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
inject = dict(reply=_fault_reply__with_detail, status=httplib.BAD_REQUEST,
|
||||
description="quack-quack")
|
||||
inject = dict(reply=_fault_reply__with_detail,
|
||||
status=http_client.BAD_REQUEST, description="quack-quack")
|
||||
e = pytest.raises(Exception, client.service.f, __inject=inject).value
|
||||
assert e.__class__ is Exception
|
||||
assert e.args[0][0] == httplib.BAD_REQUEST
|
||||
assert e.args[0][1] == "quack-quack"
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert e.args[0][0] == http_client.BAD_REQUEST
|
||||
assert e.args[0][1] == "quack-quack"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
def test_reply_error_with_detail_without_fault():
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
|
||||
for http_status in (httplib.OK, httplib.INTERNAL_SERVER_ERROR):
|
||||
for http_status in (http_client.OK, http_client.INTERNAL_SERVER_ERROR):
|
||||
status, fault = client.service.f(__inject=dict(
|
||||
reply=_fault_reply__with_detail, status=http_status))
|
||||
assert status == httplib.INTERNAL_SERVER_ERROR
|
||||
assert status == http_client.INTERNAL_SERVER_ERROR
|
||||
_test_fault(fault, True)
|
||||
|
||||
status, fault = client.service.f(__inject=dict(
|
||||
reply=_fault_reply__with_detail, status=httplib.BAD_REQUEST))
|
||||
assert status == httplib.BAD_REQUEST
|
||||
reply=_fault_reply__with_detail, status=http_client.BAD_REQUEST))
|
||||
assert status == http_client.BAD_REQUEST
|
||||
assert fault == "injected reply"
|
||||
|
||||
status, fault = client.service.f(__inject=dict(
|
||||
reply=_fault_reply__with_detail, status=httplib.BAD_REQUEST,
|
||||
reply=_fault_reply__with_detail, status=http_client.BAD_REQUEST,
|
||||
description="haleluja"))
|
||||
assert status == httplib.BAD_REQUEST
|
||||
assert status == http_client.BAD_REQUEST
|
||||
assert fault == "haleluja"
|
||||
|
||||
|
||||
def test_reply_error_without_detail_with_fault(monkeypatch):
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=True)
|
||||
|
||||
for http_status in (httplib.OK, httplib.INTERNAL_SERVER_ERROR):
|
||||
for http_status in (http_client.OK, http_client.INTERNAL_SERVER_ERROR):
|
||||
inject = dict(reply=_fault_reply__without_detail, status=http_status)
|
||||
e = pytest.raises(suds.WebFault, client.service.f, __inject=inject)
|
||||
e = e.value
|
||||
_test_fault(e.fault, False)
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
assert str(e) == "Server raised fault: 'Dummy error.'"
|
||||
try:
|
||||
e = e.value
|
||||
_test_fault(e.fault, False)
|
||||
assert e.document.__class__ is suds.sax.document.Document
|
||||
assert str(e) == "Server raised fault: 'Dummy error.'"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
inject = dict(reply=_fault_reply__with_detail, status=httplib.BAD_REQUEST,
|
||||
description="quack-quack")
|
||||
inject = dict(reply=_fault_reply__with_detail,
|
||||
status=http_client.BAD_REQUEST, description="quack-quack")
|
||||
e = pytest.raises(Exception, client.service.f, __inject=inject).value
|
||||
assert e.__class__ is Exception
|
||||
assert e.args[0][0] == httplib.BAD_REQUEST
|
||||
assert e.args[0][1] == "quack-quack"
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert e.args[0][0] == http_client.BAD_REQUEST
|
||||
assert e.args[0][1] == "quack-quack"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
def test_reply_error_without_detail_without_fault():
|
||||
client = tests.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
client = testutils.client_from_wsdl(_wsdl__simple_f, faults=False)
|
||||
|
||||
for http_status in (httplib.OK, httplib.INTERNAL_SERVER_ERROR):
|
||||
for http_status in (http_client.OK, http_client.INTERNAL_SERVER_ERROR):
|
||||
status, fault = client.service.f(__inject=dict(
|
||||
reply=_fault_reply__without_detail, status=http_status))
|
||||
assert status == httplib.INTERNAL_SERVER_ERROR
|
||||
assert status == http_client.INTERNAL_SERVER_ERROR
|
||||
_test_fault(fault, False)
|
||||
|
||||
status, fault = client.service.f(__inject=dict(
|
||||
reply=_fault_reply__without_detail, status=httplib.BAD_REQUEST,
|
||||
reply=_fault_reply__without_detail, status=http_client.BAD_REQUEST,
|
||||
description="kung-fu-fui"))
|
||||
assert status == httplib.BAD_REQUEST
|
||||
assert status == http_client.BAD_REQUEST
|
||||
assert fault == "kung-fu-fui"
|
||||
|
||||
|
||||
def test_simple_bare_and_wrapped_output():
|
||||
# Prepare web service proxies.
|
||||
client_bare = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_bare = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="fResponse" type="xsd:string"/>""",
|
||||
output="fResponse"))
|
||||
client_wrapped = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_wrapped = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -390,7 +409,7 @@ def test_simple_bare_and_wrapped_output():
|
|||
|
||||
|
||||
def test_wrapped_sequence_output():
|
||||
client = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -439,7 +458,8 @@ def _attributes(object):
|
|||
|
||||
def _isOutputWrapped(client, method_name):
|
||||
assert len(client.wsdl.bindings) == 1
|
||||
operation = client.wsdl.bindings.values()[0].operations[method_name]
|
||||
binding = next(itervalues(client.wsdl.bindings))
|
||||
operation = binding.operations[method_name]
|
||||
return operation.soap.output.body.wrapped
|
||||
|
||||
|
||||
|
@ -483,7 +503,7 @@ _fault_reply__without_detail = suds.byte_str("""\
|
|||
</env:Envelope>
|
||||
""")
|
||||
|
||||
_wsdl__simple_f = tests.wsdl("""\
|
||||
_wsdl__simple_f = testutils.wsdl("""\
|
||||
<xsd:element name="fResponse">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
|
|
@ -28,25 +28,24 @@ then passing that wrapper object instead.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.store
|
||||
import tests
|
||||
from tests.compare_sax import CompareSAX
|
||||
from testutils.compare_sax import CompareSAX
|
||||
|
||||
import pytest
|
||||
from six import iterkeys, itervalues, next, u
|
||||
|
||||
|
||||
# TODO: Update the current restriction type output parameter handling so such
|
||||
#TODO: Update the current restriction type output parameter handling so such
|
||||
# parameters get converted to the correct Python data type based on the
|
||||
# restriction's underlying data type.
|
||||
@pytest.mark.xfail
|
||||
def test_bare_input_restriction_types():
|
||||
client_unnamed = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_unnamed = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Elemento">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
|
@ -57,7 +56,7 @@ def test_bare_input_restriction_types():
|
|||
</xsd:simpleType>
|
||||
</xsd:element>""", input="Elemento", operation_name="f"))
|
||||
|
||||
client_named = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_named = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:simpleType name="MyType">
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="alfa"/>
|
||||
|
@ -380,9 +379,9 @@ def parametrize_single_element_input_test(param_names, param_values):
|
|||
))
|
||||
def test_document_literal_request_for_single_element_input(xsd,
|
||||
external_element_name, args, request_body):
|
||||
wsdl = tests.wsdl(xsd, input=external_element_name,
|
||||
wsdl = testutils.wsdl(xsd, input=external_element_name,
|
||||
xsd_target_namespace="dr. Doolittle", operation_name="f")
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
_assert_request_content(client.service.f(*args), """\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
|
@ -393,7 +392,7 @@ def test_document_literal_request_for_single_element_input(xsd,
|
|||
|
||||
def test_disabling_automated_simple_interface_unwrapping():
|
||||
xsd_target_namespace = "woof"
|
||||
wsdl = tests.wsdl("""\
|
||||
wsdl = testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -402,7 +401,7 @@ def test_disabling_automated_simple_interface_unwrapping():
|
|||
</xsd:complexType>
|
||||
</xsd:element>""", input="Wrapper", operation_name="f",
|
||||
xsd_target_namespace=xsd_target_namespace)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True,
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True,
|
||||
unwrap=False)
|
||||
assert not _is_input_wrapped(client, "f")
|
||||
element_data = "Wonderwall"
|
||||
|
@ -510,7 +509,7 @@ def test_invalid_input_parameter_type_handling():
|
|||
|
||||
"""
|
||||
xsd_target_namespace = "1234567890"
|
||||
wsdl = tests.wsdl("""\
|
||||
wsdl = testutils.wsdl("""\
|
||||
<xsd:complexType name="Freakazoid">
|
||||
<xsd:sequence>
|
||||
<xsd:element name="freak1" type="xsd:string"/>
|
||||
|
@ -528,7 +527,7 @@ def test_invalid_input_parameter_type_handling():
|
|||
</xsd:complexType>
|
||||
</xsd:element>""", input="Wrapper", operation_name="f",
|
||||
xsd_target_namespace=xsd_target_namespace)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
|
||||
# Passing an unrelated Python type value.
|
||||
class SomeType:
|
||||
|
@ -573,7 +572,7 @@ def test_invalid_input_parameter_type_handling():
|
|||
def test_missing_parameters():
|
||||
"""Missing non-optional parameters should get passed as empty values."""
|
||||
xsd_target_namespace = "plonker"
|
||||
service = _service_from_wsdl(tests.wsdl("""\
|
||||
service = _service_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -596,17 +595,17 @@ def test_missing_parameters():
|
|||
</Body>
|
||||
</Envelope>""" % (xsd_target_namespace,))
|
||||
|
||||
_assert_request_content(service.f(u"Pero Ždero"), """\
|
||||
_assert_request_content(service.f((u("Pero \u017Ddero"))), u("""\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<Header/>
|
||||
<Body>
|
||||
<Wrapper xmlns="%s">
|
||||
<aString>Pero Ždero</aString>
|
||||
<aString>Pero \u017Ddero</aString>
|
||||
<anInteger/>
|
||||
</Wrapper>
|
||||
</Body>
|
||||
</Envelope>""" % (xsd_target_namespace,))
|
||||
</Envelope>""") % (xsd_target_namespace,))
|
||||
|
||||
_assert_request_content(service.f(anInteger=666), """\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
@ -657,7 +656,7 @@ def test_named_parameter():
|
|||
|
||||
# Test different ways to make the same web service operation call.
|
||||
xsd_target_namespace = "qwerty"
|
||||
service = _service_from_wsdl(tests.wsdl("""\
|
||||
service = _service_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -686,7 +685,7 @@ def test_named_parameter():
|
|||
# The order of parameters in the constructed SOAP request should depend
|
||||
# only on the initial WSDL schema.
|
||||
xsd_target_namespace = "abracadabra"
|
||||
service = _service_from_wsdl(tests.wsdl("""\
|
||||
service = _service_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -716,7 +715,7 @@ def test_named_parameter():
|
|||
def test_optional_parameter_handling():
|
||||
"""Missing optional parameters should not get passed at all."""
|
||||
xsd_target_namespace = "RoOfIe"
|
||||
service = _service_from_wsdl(tests.wsdl("""\
|
||||
service = _service_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -843,7 +842,7 @@ def test_SOAP_headers():
|
|||
</wsdl:definitions>
|
||||
""")
|
||||
header_data = "fools rush in where angels fear to tread"
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client.options.soapheaders = header_data
|
||||
_assert_request_content(client.service.my_operation(), """\
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
@ -862,7 +861,7 @@ def test_twice_wrapped_parameter():
|
|||
|
||||
"""
|
||||
xsd_target_namespace = "spank me"
|
||||
wsdl = tests.wsdl("""\
|
||||
wsdl = testutils.wsdl("""\
|
||||
<xsd:element name="Wrapper1">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
|
@ -877,7 +876,7 @@ def test_twice_wrapped_parameter():
|
|||
</xsd:complexType>
|
||||
</xsd:element>""", input="Wrapper1", operation_name="f",
|
||||
xsd_target_namespace=xsd_target_namespace)
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
|
||||
assert _is_input_wrapped(client, "f")
|
||||
|
||||
|
@ -905,13 +904,13 @@ def test_twice_wrapped_parameter():
|
|||
# Web service operation calls made with 'invalid' parameters.
|
||||
def test_invalid_parameter(**kwargs):
|
||||
assert len(kwargs) == 1
|
||||
element = kwargs.keys()[0]
|
||||
expected = "f() got an unexpected keyword argument '%s'" % (element,)
|
||||
keyword = next(iterkeys(kwargs))
|
||||
expected = "f() got an unexpected keyword argument '%s'" % (keyword,)
|
||||
e = pytest.raises(TypeError, client.service.f, **kwargs).value
|
||||
try:
|
||||
assert str(e) == expected
|
||||
finally:
|
||||
del e
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
test_invalid_parameter(Elemento=value)
|
||||
test_invalid_parameter(Wrapper1=value)
|
||||
|
||||
|
@ -921,9 +920,9 @@ def test_wrapped_parameter(monkeypatch):
|
|||
|
||||
# Prepare web service proxies.
|
||||
def client(xsd, *input):
|
||||
wsdl = tests.wsdl(xsd, input=input, xsd_target_namespace="toolyan",
|
||||
wsdl = testutils.wsdl(xsd, input=input, xsd_target_namespace="toolyan",
|
||||
operation_name="f")
|
||||
return tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
return testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client_bare_single = client("""\
|
||||
<xsd:element name="Elemento" type="xsd:string"/>""", "Elemento")
|
||||
client_bare_multiple_simple = client("""\
|
||||
|
@ -995,7 +994,11 @@ def test_wrapped_parameter(monkeypatch):
|
|||
# Suds library's automatic structure unwrapping prevents us from specifying
|
||||
# the external wrapper structure directly.
|
||||
e = pytest.raises(TypeError, client_wrapped_unnamed.service.f, Wrapper="A")
|
||||
assert str(e.value) == "f() got an unexpected keyword argument 'Wrapper'"
|
||||
try:
|
||||
expected = "f() got an unexpected keyword argument 'Wrapper'"
|
||||
assert str(e.value) == expected
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
# Multiple parameter web service operations are never automatically
|
||||
# unwrapped.
|
||||
|
@ -1030,7 +1033,8 @@ def _assert_request_content(request, expected_xml):
|
|||
|
||||
def _is_input_wrapped(client, method_name):
|
||||
assert len(client.wsdl.bindings) == 1
|
||||
operation = client.wsdl.bindings.values()[0].operations[method_name]
|
||||
binding = next(itervalues(client.wsdl.bindings))
|
||||
operation = binding.operations[method_name]
|
||||
return operation.soap.input.body.wrapped
|
||||
|
||||
|
||||
|
@ -1042,4 +1046,4 @@ def _service_from_wsdl(wsdl):
|
|||
invocation requests and does not attempt to actually send them.
|
||||
|
||||
"""
|
||||
return tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True).service
|
||||
return testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True).service
|
||||
|
|
|
@ -23,9 +23,8 @@ Implemented using the 'pytest' testing framework.
|
|||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
import testutils
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds.sax.enc
|
||||
|
||||
|
|
|
@ -25,16 +25,15 @@ tests get added to it and it acquires more structure.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import tests
|
||||
from tests.compare_sax import CompareSAX
|
||||
from testutils.compare_sax import CompareSAX
|
||||
|
||||
import pytest
|
||||
from six import itervalues, next
|
||||
|
||||
import re
|
||||
import xml.sax
|
||||
|
@ -59,7 +58,7 @@ def test_choice_parameter_implementation_inconsistencies():
|
|||
|
||||
"""
|
||||
def client(x, y):
|
||||
return tests.client_from_wsdl(tests.wsdl(x, input=y))
|
||||
return testutils.client_from_wsdl(testutils.wsdl(x, input=y))
|
||||
|
||||
client_simple_short = client("""\
|
||||
<xsd:element name="Elemento" type="xsd:string"/>""", "Elemento")
|
||||
|
@ -90,13 +89,13 @@ def test_choice_parameter_implementation_inconsistencies():
|
|||
|
||||
|
||||
def test_converting_client_to_string_must_not_raise_an_exception():
|
||||
client = tests.client_from_wsdl(suds.byte_str(
|
||||
client = testutils.client_from_wsdl(suds.byte_str(
|
||||
"<?xml version='1.0' encoding='UTF-8'?><root/>"))
|
||||
str(client)
|
||||
|
||||
|
||||
def test_converting_metadata_to_string():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -145,19 +144,23 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
def test_empty_invalid_WSDL(monkeypatch):
|
||||
wsdl = suds.byte_str("")
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(xml.sax.SAXParseException, tests.client_from_wsdl, wsdl)
|
||||
assert e.value.getMessage() == "no element found"
|
||||
e = pytest.raises(xml.sax.SAXParseException, testutils.client_from_wsdl,
|
||||
wsdl)
|
||||
try:
|
||||
assert e.value.getMessage() == "no element found"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
def test_empty_valid_WSDL():
|
||||
client = tests.client_from_wsdl(suds.byte_str(
|
||||
client = testutils.client_from_wsdl(suds.byte_str(
|
||||
"<?xml version='1.0' encoding='UTF-8'?><root/>"))
|
||||
assert not client.wsdl.services, "No service definitions must be read " \
|
||||
"from an empty WSDL."
|
||||
|
||||
|
||||
def test_enumeration_type_string_should_contain_its_value():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -211,7 +214,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_global_sequence_in_a_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -296,7 +299,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_local_choice():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -373,7 +376,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_local_choice_in_a_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -473,7 +476,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_local_sequence_in_a_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -577,7 +580,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_sequence_in_a_choice():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -666,7 +669,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_sequence_in_a_choice_in_a_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -753,7 +756,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_function_parameters_strings():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -831,7 +834,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_global_enumeration():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -894,7 +897,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_global_sequence_in_a_global_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -980,7 +983,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_global_string_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1062,7 +1065,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_local_sequence_in_a_global_sequence():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1153,7 +1156,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_no_trailing_comma_in_function_prototype_description_string__0():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1200,7 +1203,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_no_trailing_comma_in_function_prototype_description_string__1():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1249,7 +1252,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_no_trailing_comma_in_function_prototype_description_string__3():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1300,7 +1303,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_no_types():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1336,10 +1339,14 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_parameter_referencing_missing_element(monkeypatch):
|
||||
wsdl = tests.wsdl("", input="missingElement", xsd_target_namespace="aaa")
|
||||
wsdl = testutils.wsdl("", input="missingElement",
|
||||
xsd_target_namespace="aaa")
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(suds.TypeNotFound, tests.client_from_wsdl, wsdl).value
|
||||
assert str(e) == "Type not found: '(missingElement, aaa, )'"
|
||||
e = pytest.raises(suds.TypeNotFound, testutils.client_from_wsdl, wsdl)
|
||||
try:
|
||||
assert str(e.value) == "Type not found: '(missingElement, aaa, )'"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
#TODO: Update the current restriction type input parameter handling so they get
|
||||
|
@ -1347,7 +1354,7 @@ def test_parameter_referencing_missing_element(monkeypatch):
|
|||
# interpreted as a separate input parameter.
|
||||
@pytest.mark.xfail
|
||||
def test_restrictions():
|
||||
client_unnamed = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_unnamed = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:element name="Elemento">
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:int">
|
||||
|
@ -1358,7 +1365,7 @@ def test_restrictions():
|
|||
</xsd:simpleType>
|
||||
</xsd:element>""", input="Elemento"))
|
||||
|
||||
client_named = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_named = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:simpleType name="MyType">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:enumeration value="1"/>
|
||||
|
@ -1368,7 +1375,7 @@ def test_restrictions():
|
|||
</xsd:simpleType>
|
||||
<xsd:element name="Elemento" type="ns:MyType"/>""", input="Elemento"))
|
||||
|
||||
client_twice_restricted = tests.client_from_wsdl(tests.wsdl("""\
|
||||
client_twice_restricted = testutils.client_from_wsdl(testutils.wsdl("""\
|
||||
<xsd:simpleType name="MyTypeGeneric">
|
||||
<xsd:restriction base="xsd:int">
|
||||
<xsd:enumeration value="1"/>
|
||||
|
@ -1420,7 +1427,7 @@ def test_restrictions():
|
|||
|
||||
|
||||
def test_schema_node_occurrences():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1509,7 +1516,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_schema_node_resolve():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1590,7 +1597,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_schema_node_resolve__nobuiltin_caching():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1638,7 +1645,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_schema_node_resolve__invalid_type():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1667,7 +1674,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_schema_node_resolve__references():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1744,7 +1751,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_schema_object_child_access_by_index():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1813,7 +1820,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_simple_wsdl():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
@ -1923,7 +1930,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
assert binding_qname == ("dummy", "my-namespace")
|
||||
assert binding.__class__ is suds.wsdl.Binding
|
||||
assert len(binding.operations) == 1
|
||||
operation = binding.operations.values()[0]
|
||||
operation = next(itervalues(binding.operations))
|
||||
input = operation.soap.input.body
|
||||
output = operation.soap.output.body
|
||||
assert len(input.parts) == 1
|
||||
|
@ -1960,7 +1967,7 @@ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
|
|||
|
||||
|
||||
def test_wsdl_schema_content():
|
||||
client = tests.client_from_wsdl(suds.byte_str("""\
|
||||
client = testutils.client_from_wsdl(suds.byte_str("""\
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<wsdl:definitions targetNamespace="my-namespace"
|
||||
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
|
||||
|
|
|
@ -23,12 +23,10 @@ Implemented using the 'pytest' testing framework.
|
|||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
import testutils
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
from suds.sax.date import FixedOffsetTimezone, UtcTimezone
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
|
||||
|
|
|
@ -23,15 +23,15 @@ Implemented using the 'pytest' testing framework.
|
|||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
import testutils
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
from suds.transport import Reply, Request, Transport
|
||||
import suds.transport.options
|
||||
|
||||
import pytest
|
||||
from six import b, text_type, u, unichr
|
||||
|
||||
import sys
|
||||
|
||||
|
@ -48,45 +48,49 @@ class TestBaseTransportClass:
|
|||
transport = Transport()
|
||||
f = getattr(transport, method_name)
|
||||
e = pytest.raises(Exception, f, "whatever").value
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "not-implemented"
|
||||
try:
|
||||
assert e.__class__ is Exception
|
||||
assert str(e) == "not-implemented"
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestReply:
|
||||
|
||||
@pytest.mark.parametrize(("code", "headers", "message"), (
|
||||
(1, {}, None),
|
||||
(1, {}, "ola"),
|
||||
(1, {}, suds.byte_str("ola")),
|
||||
(1, {}, u("ola")),
|
||||
(1, {}, b("ola")),
|
||||
(1, {}, object()),
|
||||
(1, {}, u"šuć-muć 中原千军逐蒋\n城楼万众检阅".encode("utf-8")),
|
||||
(2, {"semper": "fi"}, u"中原千军逐蒋\n城楼万众检阅")))
|
||||
(1, {}, u("\u0161u\u0107-mu\u0107 \u4E2D\u539F\u5343\n\u57CE")),
|
||||
(2, {"semper": "fi"}, u("\u4E2D\u539F\u5343\n\u57CE"))))
|
||||
def test_construction(self, code, headers, message):
|
||||
reply = Reply(code, headers, message)
|
||||
assert reply.code is code
|
||||
assert reply.headers is headers
|
||||
assert reply.message is message
|
||||
|
||||
@pytest.mark.parametrize("message", [x.encode("utf-8") for x in (
|
||||
u"",
|
||||
u"for a bitch it's haaaard...",
|
||||
u"""\
|
||||
@pytest.mark.parametrize("message", [u(x).encode("utf-8") for x in (
|
||||
"",
|
||||
"for a bitch it's haaaard...",
|
||||
"""\
|
||||
I'm here to kick ass,
|
||||
and chew bubble gum...
|
||||
and I'm all out of gum.""",
|
||||
u"šuć-muć pa ožeži.. za 100 €\n\nwith multiple\nlines...",
|
||||
u"\n\n\n\n\n\n",
|
||||
u"中原千军逐蒋")])
|
||||
"\u0161u\u0107-mu\u0107 pa o\u017Ee\u017Ei.. za 100 \u20AC\n\n"
|
||||
"with multiple\nlines...",
|
||||
"\n\n\n\n\n\n",
|
||||
"\u4E2D\u539F\u5343\u519B\u9010\u848B")])
|
||||
def test_string_representation(self, message):
|
||||
code = 17
|
||||
reply = Reply(code, {"aaa": 1}, message)
|
||||
expected = u"""\
|
||||
expected = u("""\
|
||||
CODE: %s
|
||||
HEADERS: %s
|
||||
MESSAGE:
|
||||
%s""" % (code, reply.headers, message.decode("raw_unicode_escape"))
|
||||
assert unicode(reply) == expected
|
||||
if sys.version_info < (3, 0):
|
||||
%s""") % (code, reply.headers, message.decode("raw_unicode_escape"))
|
||||
assert text_type(reply) == expected
|
||||
if sys.version_info < (3,):
|
||||
assert str(reply) == expected.encode("utf-8")
|
||||
|
||||
|
||||
|
@ -95,7 +99,7 @@ class TestRequest:
|
|||
@pytest.mark.parametrize("message", (
|
||||
None,
|
||||
"it's hard out here...",
|
||||
u"城楼万众检阅"))
|
||||
u("\u57CE\u697C\u4E07\u4F17\u68C0\u9605")))
|
||||
def test_construct(self, message):
|
||||
# Always use the same URL as different ways to specify a Request's URL
|
||||
# are tested separately.
|
||||
|
@ -111,10 +115,10 @@ class TestRequest:
|
|||
assert request.message is None
|
||||
|
||||
test_non_ASCII_URLs = [
|
||||
u"中原千军逐蒋",
|
||||
u"城楼万众检阅"] + [
|
||||
u("\u4E2D\u539F\u5343\u519B\u9010\u848B"),
|
||||
u("\u57CE\u697C\u4E07\u4F17\u68C0\u9605")] + [
|
||||
url_prefix + url_suffix
|
||||
for url_prefix in (u"", u"Jurko")
|
||||
for url_prefix in (u(""), u("Jurko"))
|
||||
for url_suffix in (unichr(128), unichr(200), unichr(1000))]
|
||||
@pytest.mark.parametrize("url",
|
||||
test_non_ASCII_URLs + # unicode strings
|
||||
|
@ -131,29 +135,30 @@ class TestRequest:
|
|||
I'm here to kick ass,
|
||||
and chew bubble gum...
|
||||
and I'm all out of gum."""),
|
||||
("", {}, u"šuć-muć pa ožeži.. za 100 €\n\nwith multiple\nlines..."),
|
||||
("", {}, u("\u0161u\u0107-mu\u0107 pa o\u017Ee\u017Ei.. za 100 "
|
||||
"\u20AC\n\nwith multiple\nlines...")),
|
||||
("", {}, "\n\n\n\n\n\n"),
|
||||
("", {}, u"中原千军逐蒋")))
|
||||
("", {}, u("\u4E2D\u539F\u5343\u519B\u9010\u848B"))))
|
||||
def test_string_representation_with_message(self, url, headers, message):
|
||||
for key, value in headers.items():
|
||||
old_key = key
|
||||
if isinstance(key, unicode):
|
||||
if isinstance(key, text_type):
|
||||
key = key.encode("utf-8")
|
||||
del headers[old_key]
|
||||
if isinstance(value, unicode):
|
||||
if isinstance(value, text_type):
|
||||
value = value.encode("utf-8")
|
||||
headers[key] = value
|
||||
if isinstance(message, unicode):
|
||||
if isinstance(message, text_type):
|
||||
message = message.encode("utf-8")
|
||||
request = Request(url, message)
|
||||
request.headers = headers
|
||||
expected = u"""\
|
||||
expected = u("""\
|
||||
URL: %s
|
||||
HEADERS: %s
|
||||
MESSAGE:
|
||||
%s""" % (url, request.headers, message.decode("raw_unicode_escape"))
|
||||
assert unicode(request) == expected
|
||||
if sys.version_info < (3, 0):
|
||||
%s""") % (url, request.headers, message.decode("raw_unicode_escape"))
|
||||
assert text_type(request) == expected
|
||||
if sys.version_info < (3,):
|
||||
assert str(request) == expected.encode("utf-8")
|
||||
|
||||
def test_string_representation_with_no_message(self):
|
||||
|
@ -161,23 +166,23 @@ MESSAGE:
|
|||
headers = {suds.byte_str("yuck"): suds.byte_str("ptooiii...")}
|
||||
request = Request(url)
|
||||
request.headers = headers
|
||||
expected = u"""\
|
||||
expected = u("""\
|
||||
URL: %s
|
||||
HEADERS: %s""" % (url, request.headers)
|
||||
assert unicode(request) == expected
|
||||
if sys.version_info < (3, 0):
|
||||
HEADERS: %s""") % (url, request.headers)
|
||||
assert text_type(request) == expected
|
||||
if sys.version_info < (3,):
|
||||
assert str(request) == expected.encode("utf-8")
|
||||
|
||||
test_URLs = [
|
||||
u"",
|
||||
u"http://host/path/name",
|
||||
u"cogito://ergo/sum",
|
||||
u"haleluya",
|
||||
u"look at me flyyyyyyyy",
|
||||
u(""),
|
||||
u("http://host/path/name"),
|
||||
u("cogito://ergo/sum"),
|
||||
u("haleluya"),
|
||||
u("look at me flyyyyyyyy"),
|
||||
unichr(0),
|
||||
unichr(127),
|
||||
u"Jurko" + unichr(0),
|
||||
u"Jurko" + unichr(127)]
|
||||
u("Jurko") + unichr(0),
|
||||
u("Jurko") + unichr(127)]
|
||||
@pytest.mark.parametrize("url", test_URLs + [
|
||||
url.encode("ascii") for url in test_URLs])
|
||||
def test_URL(self, url):
|
||||
|
@ -191,7 +196,7 @@ HEADERS: %s""" % (url, request.headers)
|
|||
assert isinstance(request.url, str)
|
||||
if url.__class__ is str:
|
||||
assert request.url is url
|
||||
elif url.__class__ is unicode:
|
||||
elif url.__class__ is u:
|
||||
assert request.url == url.encode("ascii") # Python 2.
|
||||
else:
|
||||
assert request.url == url.decode("ascii") # Python 3.
|
||||
|
|
|
@ -22,28 +22,31 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds
|
||||
import suds.transport
|
||||
import suds.transport.http
|
||||
import tests
|
||||
|
||||
import pytest
|
||||
from six import u
|
||||
from six.moves import http_client
|
||||
from six.moves.urllib.error import HTTPError
|
||||
from six.moves.urllib.request import ProxyHandler
|
||||
|
||||
import base64
|
||||
import httplib
|
||||
import re
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
if sys.version_info >= (3, 0):
|
||||
urllib_request = urllib.request
|
||||
# We can not use six.moves modules for this since we want to monkey-patch the
|
||||
# exact underlying urllib2/urllib.request module in our tests and not just
|
||||
# their six.moves proxy module.
|
||||
if sys.version_info < (3,):
|
||||
import urllib2 as urllib_request
|
||||
else:
|
||||
urllib_request = urllib2
|
||||
import urllib.request as urllib_request
|
||||
|
||||
|
||||
class MustNotBeCalled(Exception):
|
||||
|
@ -103,11 +106,11 @@ class CountedMock(object):
|
|||
|
||||
class MockFP:
|
||||
"""
|
||||
Mock FP 'File object' as stored inside a urllib2.HTTPError exception.
|
||||
Mock FP 'File object' as stored inside Python's HTTPError exception.
|
||||
|
||||
Must have several 'File object' methods defined on it as Python's
|
||||
urllib2.HTTPError implementation expects them and stores references to them
|
||||
internally, at least with Python 2.4.
|
||||
Must have several 'File object' methods defined on it as Python's HTTPError
|
||||
implementation expects them and stores references to them internally, at
|
||||
least with Python 2.4.
|
||||
|
||||
"""
|
||||
|
||||
|
@ -171,7 +174,7 @@ def assert_default_transport(transport):
|
|||
assert transport.urlopener is None
|
||||
|
||||
|
||||
def create_request(url="protocol://default-url", data=u"Rumpelstiltskin"):
|
||||
def create_request(url="protocol://default-url", data=u("Rumpelstiltskin")):
|
||||
"""Test utility constructing a suds.transport.Request instance."""
|
||||
return suds.transport.Request(url, data)
|
||||
|
||||
|
@ -304,7 +307,7 @@ def test_sending_using_network_sockets(send_method, monkeypatch):
|
|||
url_relative = "svc"
|
||||
url = "http://%s/%s" % (host_port, url_relative)
|
||||
partial_ascii_byte_data = suds.byte_str("Muka-laka-hiki")
|
||||
non_ascii_byte_data = u"Дмитровский район".encode("utf-8")
|
||||
non_ascii_byte_data = u("\u0414\u043C\u0438 \u0442\u0440").encode("utf-8")
|
||||
non_ascii_byte_data += partial_ascii_byte_data
|
||||
mocker = Mocker(host, port)
|
||||
monkeypatch.setattr("socket.getaddrinfo", mocker.getaddrinfo)
|
||||
|
@ -359,7 +362,7 @@ class TestSendingToURLWithAMissingProtocolIdentifier:
|
|||
"my no-protocol URL",
|
||||
":my no-protocol URL"))
|
||||
|
||||
@pytest.mark.skipif(sys.version_info >= (3, 0), reason="Python 2 specific")
|
||||
@pytest.mark.skipif(sys.version_info >= (3,), reason="Python 2 specific")
|
||||
@invalid_URL_parametrization
|
||||
def test_python2(self, url, send_method):
|
||||
transport = suds.transport.http.HttpTransport()
|
||||
|
@ -367,7 +370,7 @@ class TestSendingToURLWithAMissingProtocolIdentifier:
|
|||
request = create_request(url)
|
||||
pytest.raises(MyException, send_method, transport, request)
|
||||
|
||||
@pytest.mark.skipif(sys.version_info < (3, 0), reason="Python 3+ specific")
|
||||
@pytest.mark.skipif(sys.version_info < (3,), reason="Python 3+ specific")
|
||||
@invalid_URL_parametrization
|
||||
def test_python3(self, url, send_method, monkeypatch):
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
|
@ -375,7 +378,10 @@ class TestSendingToURLWithAMissingProtocolIdentifier:
|
|||
transport.urlopener = MockURLOpenerSaboteur()
|
||||
request = create_request(url)
|
||||
e = pytest.raises(ValueError, send_method, transport, request)
|
||||
assert "unknown url type" in str(e)
|
||||
try:
|
||||
assert "unknown url type" in str(e)
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestURLOpenerUsage:
|
||||
|
@ -406,20 +412,20 @@ class TestURLOpenerUsage:
|
|||
msg = object()
|
||||
if hdrs is Undefined:
|
||||
hdrs = object()
|
||||
return urllib2.HTTPError(url=url, code=code, msg=msg, hdrs=hdrs, fp=fp)
|
||||
return HTTPError(url=url, code=code, msg=msg, hdrs=hdrs, fp=fp)
|
||||
|
||||
@pytest.mark.parametrize("status_code", (
|
||||
httplib.ACCEPTED,
|
||||
httplib.NO_CONTENT,
|
||||
httplib.RESET_CONTENT,
|
||||
httplib.MOVED_PERMANENTLY,
|
||||
httplib.BAD_REQUEST,
|
||||
httplib.PAYMENT_REQUIRED,
|
||||
httplib.FORBIDDEN,
|
||||
httplib.NOT_FOUND,
|
||||
httplib.INTERNAL_SERVER_ERROR,
|
||||
httplib.NOT_IMPLEMENTED,
|
||||
httplib.HTTP_VERSION_NOT_SUPPORTED))
|
||||
http_client.ACCEPTED,
|
||||
http_client.NO_CONTENT,
|
||||
http_client.RESET_CONTENT,
|
||||
http_client.MOVED_PERMANENTLY,
|
||||
http_client.BAD_REQUEST,
|
||||
http_client.PAYMENT_REQUIRED,
|
||||
http_client.FORBIDDEN,
|
||||
http_client.NOT_FOUND,
|
||||
http_client.INTERNAL_SERVER_ERROR,
|
||||
http_client.NOT_IMPLEMENTED,
|
||||
http_client.HTTP_VERSION_NOT_SUPPORTED))
|
||||
def test_open_propagating_HTTPError_exceptions(self, status_code,
|
||||
monkeypatch):
|
||||
"""
|
||||
|
@ -437,16 +443,18 @@ class TestURLOpenerUsage:
|
|||
|
||||
# Execute.
|
||||
e = pytest.raises(suds.transport.TransportError, t.open, request).value
|
||||
|
||||
# Verify.
|
||||
assert e.args == (str(e_original),)
|
||||
assert e.httpcode is status_code
|
||||
assert e.fp is fp
|
||||
try:
|
||||
# Verify.
|
||||
assert e.args == (str(e_original),)
|
||||
assert e.httpcode is status_code
|
||||
assert e.fp is fp
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
@pytest.mark.xfail(reason="original suds library bug")
|
||||
@pytest.mark.parametrize("status_code", (
|
||||
httplib.ACCEPTED,
|
||||
httplib.NO_CONTENT))
|
||||
http_client.ACCEPTED,
|
||||
http_client.NO_CONTENT))
|
||||
def test_operation_invoke_with_urlopen_accept_no_content__data(self,
|
||||
status_code):
|
||||
"""
|
||||
|
@ -459,15 +467,15 @@ class TestURLOpenerUsage:
|
|||
e = self.create_HTTPError(code=status_code)
|
||||
transport = suds.transport.http.HttpTransport()
|
||||
transport.urlopener = MockURLOpenerSaboteur(open_exception=e)
|
||||
wsdl = tests.wsdl('<xsd:element name="o" type="xsd:string"/>',
|
||||
wsdl = testutils.wsdl('<xsd:element name="o" type="xsd:string"/>',
|
||||
output="o", operation_name="f")
|
||||
client = tests.client_from_wsdl(wsdl, transport=transport)
|
||||
client = testutils.client_from_wsdl(wsdl, transport=transport)
|
||||
pytest.raises(suds.transport.TransportError, client.service.f)
|
||||
|
||||
@pytest.mark.xfail(reason="original suds library bug")
|
||||
@pytest.mark.parametrize("status_code", (
|
||||
httplib.ACCEPTED,
|
||||
httplib.NO_CONTENT))
|
||||
http_client.ACCEPTED,
|
||||
http_client.NO_CONTENT))
|
||||
def test_operation_invoke_with_urlopen_accept_no_content__no_data(self,
|
||||
status_code):
|
||||
"""
|
||||
|
@ -487,9 +495,9 @@ class TestURLOpenerUsage:
|
|||
e = self.create_HTTPError(code=status_code)
|
||||
transport = suds.transport.http.HttpTransport()
|
||||
transport.urlopener = MockURLOpenerSaboteur(open_exception=e)
|
||||
wsdl = tests.wsdl('<xsd:element name="o" type="xsd:string"/>',
|
||||
wsdl = testutils.wsdl('<xsd:element name="o" type="xsd:string"/>',
|
||||
output="o", operation_name="f")
|
||||
client = tests.client_from_wsdl(wsdl, transport=transport)
|
||||
client = testutils.client_from_wsdl(wsdl, transport=transport)
|
||||
assert client.service.f() is None
|
||||
|
||||
def test_propagating_non_HTTPError_exceptions(self, send_method):
|
||||
|
@ -504,15 +512,15 @@ class TestURLOpenerUsage:
|
|||
assert pytest.raises(e.__class__, t.open, create_request()).value is e
|
||||
|
||||
@pytest.mark.parametrize("status_code", (
|
||||
httplib.RESET_CONTENT,
|
||||
httplib.MOVED_PERMANENTLY,
|
||||
httplib.BAD_REQUEST,
|
||||
httplib.PAYMENT_REQUIRED,
|
||||
httplib.FORBIDDEN,
|
||||
httplib.NOT_FOUND,
|
||||
httplib.INTERNAL_SERVER_ERROR,
|
||||
httplib.NOT_IMPLEMENTED,
|
||||
httplib.HTTP_VERSION_NOT_SUPPORTED))
|
||||
http_client.RESET_CONTENT,
|
||||
http_client.MOVED_PERMANENTLY,
|
||||
http_client.BAD_REQUEST,
|
||||
http_client.PAYMENT_REQUIRED,
|
||||
http_client.FORBIDDEN,
|
||||
http_client.NOT_FOUND,
|
||||
http_client.INTERNAL_SERVER_ERROR,
|
||||
http_client.NOT_IMPLEMENTED,
|
||||
http_client.HTTP_VERSION_NOT_SUPPORTED))
|
||||
def test_send_transforming_HTTPError_exceptions(self, status_code,
|
||||
monkeypatch):
|
||||
"""
|
||||
|
@ -532,16 +540,18 @@ class TestURLOpenerUsage:
|
|||
|
||||
# Execute.
|
||||
e = pytest.raises(suds.transport.TransportError, t.send, request).value
|
||||
|
||||
# Verify.
|
||||
assert len(e.args) == 1
|
||||
assert e.args[0] is e_original.msg
|
||||
assert e.httpcode is status_code
|
||||
assert e.fp is fp
|
||||
try:
|
||||
# Verify.
|
||||
assert len(e.args) == 1
|
||||
assert e.args[0] is e_original.msg
|
||||
assert e.httpcode is status_code
|
||||
assert e.fp is fp
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
@pytest.mark.parametrize("status_code", (
|
||||
httplib.ACCEPTED,
|
||||
httplib.NO_CONTENT))
|
||||
http_client.ACCEPTED,
|
||||
http_client.NO_CONTENT))
|
||||
def test_send_transforming_HTTPError_exceptions__accepted_no_content(self,
|
||||
status_code):
|
||||
"""
|
||||
|
@ -563,7 +573,7 @@ class TestURLOpenerUsage:
|
|||
"""
|
||||
def my_build_urlopener(*handlers):
|
||||
assert len(handlers) == 1
|
||||
assert handlers[0].__class__ is urllib2.ProxyHandler
|
||||
assert handlers[0].__class__ is ProxyHandler
|
||||
raise MyException
|
||||
monkeypatch.setattr(urllib_request, "build_opener", my_build_urlopener)
|
||||
transport = suds.transport.http.HttpTransport()
|
||||
|
@ -581,9 +591,9 @@ class TestURLOpenerUsage:
|
|||
|
||||
"""
|
||||
class MockURLOpener:
|
||||
def open(self, urllib_request, timeout=None):
|
||||
assert urllib_request.__class__ is urllib2.Request
|
||||
assert urllib_request.get_full_url() == url
|
||||
def open(self, request, timeout=None):
|
||||
assert request.__class__ is urllib_request.Request
|
||||
assert request.get_full_url() == url
|
||||
raise MyException
|
||||
transport = suds.transport.http.HttpTransport()
|
||||
transport.urlopener = MockURLOpener()
|
||||
|
|
|
@ -22,17 +22,15 @@ Implemented using the 'pytest' testing framework.
|
|||
|
||||
"""
|
||||
|
||||
import testutils
|
||||
if __name__ == "__main__":
|
||||
import __init__
|
||||
__init__.run_using_pytest(globals())
|
||||
|
||||
testutils.run_using_pytest(globals())
|
||||
|
||||
import suds.client
|
||||
import suds.sax.date
|
||||
from suds.xsd.sxbuiltin import (Factory, XAny, XBoolean, XBuiltin, XDate,
|
||||
XDateTime, XDecimal, XFloat, XInteger, XLong, XString, XTime)
|
||||
import tests
|
||||
from tests.compare_sax import CompareSAX
|
||||
from testutils.compare_sax import CompareSAX
|
||||
|
||||
import pytest
|
||||
|
||||
|
@ -43,6 +41,8 @@ import sys
|
|||
|
||||
if sys.version_info >= (2, 6):
|
||||
import fractions
|
||||
if sys.version_info >= (3,):
|
||||
long = int
|
||||
|
||||
|
||||
class _Dummy:
|
||||
|
@ -164,9 +164,9 @@ class TestXBoolean:
|
|||
|
||||
@pytest.mark.parametrize("source", (
|
||||
None,
|
||||
pytest.mark.skipif(sys.version_info >= (3, 0),
|
||||
pytest.mark.skipif(sys.version_info >= (3,),
|
||||
reason="int == long since Python 3.0")(long(0)),
|
||||
pytest.mark.skipif(sys.version_info >= (3, 0),
|
||||
pytest.mark.skipif(sys.version_info >= (3,),
|
||||
reason="int == long since Python 3.0")(long(1)),
|
||||
"x",
|
||||
"True",
|
||||
|
@ -447,13 +447,16 @@ class TestXFloat:
|
|||
"""
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(ValueError, MockXFloat().translate, source).value
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
float(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError, expected_e:
|
||||
assert str(e) == str(expected_e)
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
float(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError:
|
||||
assert str(e) == str(sys.exc_info()[1])
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestXInteger:
|
||||
|
@ -470,10 +473,10 @@ class TestXInteger:
|
|||
1,
|
||||
50,
|
||||
# long
|
||||
pytest.mark.skipif(sys.version_info >= (3, 0),
|
||||
reason="int == long since Python 3.0")(long(0)),
|
||||
pytest.mark.skipif(sys.version_info >= (3, 0),
|
||||
reason="int == long since Python 3.0")(long(1)),
|
||||
long(-50),
|
||||
long(0),
|
||||
long(1),
|
||||
long(50),
|
||||
# str
|
||||
"x",
|
||||
# other
|
||||
|
@ -504,13 +507,16 @@ class TestXInteger:
|
|||
"""
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(ValueError, MockXInteger().translate, source).value
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
int(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError, expected_e:
|
||||
assert str(e) == str(expected_e)
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
int(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError:
|
||||
assert str(e) == str(sys.exc_info()[1])
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestXLong:
|
||||
|
@ -567,13 +573,16 @@ class TestXLong:
|
|||
"""
|
||||
monkeypatch.delitem(locals(), "e", False)
|
||||
e = pytest.raises(ValueError, MockXLong().translate, source).value
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
long(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError, expected_e:
|
||||
assert str(e) == str(expected_e)
|
||||
# Using different Python interpreter versions and different source
|
||||
# strings results in different exception messages here.
|
||||
try:
|
||||
long(source)
|
||||
pytest.fail("Bad test data.")
|
||||
except ValueError:
|
||||
assert str(e) == str(sys.exc_info()[1])
|
||||
finally:
|
||||
del e # explicitly break circular reference chain in Python 3
|
||||
|
||||
|
||||
class TestXTime:
|
||||
|
@ -678,8 +687,9 @@ def test_resolving_builtin_types(monkeypatch):
|
|||
pass
|
||||
Factory.maptag("osama", MockXInteger)
|
||||
|
||||
wsdl = tests.wsdl('<xsd:element name="wu" type="xsd:osama"/>', input="wu")
|
||||
client = tests.client_from_wsdl(wsdl)
|
||||
wsdl = testutils.wsdl('<xsd:element name="wu" type="xsd:osama"/>',
|
||||
input="wu")
|
||||
client = testutils.client_from_wsdl(wsdl)
|
||||
|
||||
element, schema_object = client.sd[0].params[0]
|
||||
assert element.name == "wu"
|
||||
|
@ -705,11 +715,11 @@ def test_translation(monkeypatch):
|
|||
Factory.maptag("woof", MockType)
|
||||
|
||||
namespace = "I'm a little tea pot, short and stout..."
|
||||
wsdl = tests.wsdl("""\
|
||||
wsdl = testutils.wsdl("""\
|
||||
<xsd:element name="wi" type="xsd:woof"/>
|
||||
<xsd:element name="wo" type="xsd:woof"/>""", input="wi", output="wo",
|
||||
xsd_target_namespace=namespace, operation_name="f")
|
||||
client = tests.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
client = testutils.client_from_wsdl(wsdl, nosend=True, prettyxml=True)
|
||||
|
||||
# Check suds library's XSD schema input parameter information.
|
||||
schema = client.wsdl.schema
|
||||
|
@ -757,8 +767,8 @@ def _create_dummy_schema():
|
|||
#TODO: Find out how to construct this XSD schema object directly without
|
||||
# first having to construct a suds.client.Client from a complete WSDL
|
||||
# schema.
|
||||
wsdl = tests.wsdl('<xsd:element name="dummy"/>', input="dummy")
|
||||
client = tests.client_from_wsdl(wsdl)
|
||||
wsdl = testutils.wsdl('<xsd:element name="dummy"/>', input="dummy")
|
||||
client = testutils.client_from_wsdl(wsdl)
|
||||
return client.wsdl.schema
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
# written by: Jurko Gospodnetić ( jurko.gospodnetic@pke.hr )
|
||||
|
||||
"""
|
||||
Package containing different utilities used for suds project testing.
|
||||
|
||||
"""
|
||||
|
||||
import suds.client
|
||||
import suds.store
|
||||
|
|
@ -20,4 +20,4 @@ Assertion test utility functions shared between multiple test modules.
|
|||
|
||||
"""
|
||||
|
||||
from assertion__pytest_assert_rewrite_needed import *
|
||||
from testutils.assertion__pytest_assert_rewrite_needed import *
|
|
@ -20,4 +20,4 @@ CompareSAX test utility class.
|
|||
|
||||
"""
|
||||
|
||||
from compare_sax__pytest_assert_rewrite_needed import *
|
||||
from testutils.compare_sax__pytest_assert_rewrite_needed import *
|
|
@ -31,6 +31,8 @@ import suds.sax.document
|
|||
import suds.sax.element
|
||||
import suds.sax.parser
|
||||
|
||||
from six import text_type, u
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
|
@ -90,7 +92,7 @@ class CompareSAX:
|
|||
"""Compares two SAX XML documents."""
|
||||
self = cls()
|
||||
try:
|
||||
self.__document2document(lhs, rhs, context=u"document2document")
|
||||
self.__document2document(lhs, rhs, context="document2document")
|
||||
except Exception:
|
||||
self.__report_context()
|
||||
raise
|
||||
|
@ -105,7 +107,7 @@ class CompareSAX:
|
|||
|
||||
"""
|
||||
self = cls()
|
||||
self.__push_context(u"document2element")
|
||||
self.__push_context("document2element")
|
||||
try:
|
||||
assert document.__class__ is suds.sax.document.Document
|
||||
assert element.__class__ is suds.sax.element.Element
|
||||
|
@ -119,7 +121,7 @@ class CompareSAX:
|
|||
def element2element(cls, lhs, rhs):
|
||||
"""Compares two SAX XML elements."""
|
||||
self = cls()
|
||||
self.__push_context(u"element2element")
|
||||
self.__push_context("element2element")
|
||||
try:
|
||||
self.__element2element(lhs, rhs)
|
||||
except Exception:
|
||||
|
@ -133,7 +135,7 @@ class CompareSAX:
|
|||
try:
|
||||
lhs_doc = self.__parse_data(lhs)
|
||||
rhs_doc = self.__parse_data(rhs)
|
||||
self.__document2document(lhs_doc, rhs_doc, context=u"data2data")
|
||||
self.__document2document(lhs_doc, rhs_doc, context="data2data")
|
||||
except Exception:
|
||||
self.__report_context()
|
||||
raise
|
||||
|
@ -148,7 +150,7 @@ class CompareSAX:
|
|||
self = cls()
|
||||
try:
|
||||
rhs_doc = self.__parse_data(rhs)
|
||||
self.__document2document(lhs, rhs_doc, context=u"document2data")
|
||||
self.__document2document(lhs, rhs_doc, context="document2data")
|
||||
except Exception:
|
||||
self.__report_context()
|
||||
raise
|
||||
|
@ -174,7 +176,7 @@ class CompareSAX:
|
|||
"""
|
||||
#TODO: Make suds SAX element model consistently represent empty/missing
|
||||
# namespaces and then update both this method and its docstring.
|
||||
self.__push_context(u"namespace")
|
||||
self.__push_context("namespace")
|
||||
lhs_namespace = lhs.namespace()[1]
|
||||
rhs_namespace = rhs.namespace()[1]
|
||||
if not lhs_namespace:
|
||||
|
@ -198,7 +200,7 @@ class CompareSAX:
|
|||
"""
|
||||
#TODO: Make suds SAX element model consistently represent empty/missing
|
||||
# text content and then update both this method and its docstring.
|
||||
self.__push_context(u"text")
|
||||
self.__push_context("text")
|
||||
lhs_text = lhs.text
|
||||
rhs_text = rhs.text
|
||||
if not lhs_text:
|
||||
|
@ -225,9 +227,11 @@ class CompareSAX:
|
|||
def __element_name(element):
|
||||
"""Returns a given SAX element's name as unicode or '???' on error."""
|
||||
try:
|
||||
return unicode(element.name)
|
||||
return text_type(element.name)
|
||||
except (KeyboardInterrupt, SystemExit):
|
||||
raise
|
||||
except Exception:
|
||||
return u"???"
|
||||
return u("???")
|
||||
|
||||
def __element2element(self, lhs, rhs, context_info=(0, 1)):
|
||||
"""
|
||||
|
@ -266,10 +270,10 @@ class CompareSAX:
|
|||
if context_lhs_name == context_rhs_name:
|
||||
context_name = context_lhs_name
|
||||
else:
|
||||
context_name = u"%s/%s" % (context_lhs_name, context_rhs_name)
|
||||
context_name = "%s/%s" % (context_lhs_name, context_rhs_name)
|
||||
if count == 1:
|
||||
return u"<%s>" % (context_name,)
|
||||
return u"<%s(%d/%d)>" % (context_name, n + 1, count)
|
||||
return "<%s>" % (context_name,)
|
||||
return "<%s(%d/%d)>" % (context_name, n + 1, count)
|
||||
|
||||
@staticmethod
|
||||
def __parse_data(data):
|
||||
|
@ -278,7 +282,7 @@ class CompareSAX:
|
|||
bytes object.
|
||||
|
||||
"""
|
||||
if isinstance(data, unicode):
|
||||
if isinstance(data, text_type):
|
||||
data = data.encode("utf-8")
|
||||
return suds.sax.parser.Parser().parse(string=data)
|
||||
|
||||
|
@ -291,4 +295,4 @@ class CompareSAX:
|
|||
def __report_context(self):
|
||||
if self.__context:
|
||||
sys.stderr.write("Failed SAX XML comparison context:\n")
|
||||
sys.stderr.write(u" %s\n" % (u".".join(self.__context)))
|
||||
sys.stderr.write(" %s\n" % (".".join(self.__context)))
|
|
@ -14,9 +14,8 @@
|
|||
@for %%i in ("%~f0\..\..") do @set PROJECT_FOLDER=%%~fi
|
||||
@cd /d "%PROJECT_FOLDER%"
|
||||
|
||||
:: Python command-line options used for running specific scripts.
|
||||
:: Used pytest command-line options.
|
||||
@set PYTEST_OPTIONS=-m pytest -q -x --tb=short
|
||||
@set SETUP_OPTIONS=setup.py -q develop
|
||||
|
||||
@call :test "3.4.0 x64" "py340" || goto :fail
|
||||
@call :test "2.4.3 x86" "py243" || goto :fail
|
||||
|
@ -50,16 +49,18 @@
|
|||
@setlocal
|
||||
@set TITLE=%~1
|
||||
@set PYTHON="%~2"
|
||||
@set LOCATION=tests
|
||||
@if "%TITLE:~0,1%" == "2" goto :test__skip_build
|
||||
@echo ---------------------------------------------------------------
|
||||
@echo --- Building suds for Python %TITLE%
|
||||
@echo ---------------------------------------------------------------
|
||||
@set LOCATION=build/lib/%LOCATION%
|
||||
@if exist "build\" (rd /s /q build || exit /b -2)
|
||||
@call %PYTHON% %SETUP_OPTIONS% || exit /b -2
|
||||
@echo.
|
||||
:test__skip_build
|
||||
:: Install the project into the target Python environment in editable mode.
|
||||
:: This will actually build Python 3 sources in case we are using a Python 3
|
||||
:: environment.
|
||||
@call %PYTHON% setup.py -q develop || exit /b -2
|
||||
@cd tests
|
||||
@echo.
|
||||
@echo ---------------------------------------------------------------
|
||||
@echo --- Testing suds with Python %TITLE%
|
||||
@echo ---------------------------------------------------------------
|
||||
|
|
|
@ -25,6 +25,7 @@ The environments should have the following Python packages installed:
|
|||
* setuptools (for installing pip)
|
||||
* pip (for installing everything except itself)
|
||||
* pytest (for running the project's test suite)
|
||||
* six (Python 2/3 compatibility layer used in the project's test suite)
|
||||
* virtualenv (for creating virtual Python environments)
|
||||
plus certain specific Python versions may require additional backward
|
||||
compatibility support packages.
|
||||
|
@ -746,6 +747,7 @@ def process_pip(env, actions):
|
|||
# ----------------------------------
|
||||
|
||||
v1_4_16 = _lowest_version_string_with_prefix("1.4_16")
|
||||
v1_5 = _lowest_version_string_with_prefix("1.5")
|
||||
v1_8 = _lowest_version_string_with_prefix("1.8")
|
||||
v1_10 = _lowest_version_string_with_prefix("1.10")
|
||||
|
||||
|
@ -831,6 +833,15 @@ def add_pytest_requirements(env, requirements):
|
|||
requirements.append(requirement_spec("pytest", pytest_version))
|
||||
|
||||
|
||||
def add_six_requirements(env_version_info, requirements):
|
||||
# six release 1.5 broke compatibility with Python 2.4.x.
|
||||
if env_version_info < (2, 5):
|
||||
version_spec = "<", v1_5
|
||||
else:
|
||||
version_spec = None
|
||||
requirements.append(requirement_spec("six", version_spec))
|
||||
|
||||
|
||||
def add_virtualenv_requirements(env_version_info, requirements):
|
||||
# virtualenv releases supported on older Python versions:
|
||||
# * Python 2.4 - virtualenv 1.7.2 (not supported in 1.8.x).
|
||||
|
@ -887,6 +898,7 @@ def prepare_pip_requirements_file_if_needed(requirements):
|
|||
def prepare_pip_requirements(env):
|
||||
requirements = []
|
||||
add_pytest_requirements(env, requirements)
|
||||
add_six_requirements(env.sys_version_info, requirements)
|
||||
add_virtualenv_requirements(env.sys_version_info, requirements)
|
||||
janitor = prepare_pip_requirements_file_if_needed(requirements)
|
||||
return requirements, janitor
|
||||
|
|
|
@ -23,6 +23,10 @@ Basic configuration support shared in different development utility scripts.
|
|||
import os.path
|
||||
import sys
|
||||
|
||||
# Must not use the six Python 2/3 compatibility package from here as this
|
||||
# module gets used from the script for setting up basic development
|
||||
# environments, and that script needs to be runnable even before the six
|
||||
# package has been installed.
|
||||
if sys.version_info < (3,):
|
||||
import ConfigParser as configparser
|
||||
else:
|
||||
|
|
Loading…
Reference in New Issue