diff options
Diffstat (limited to 'python')
271 files changed, 54450 insertions, 0 deletions
diff --git a/python/Makefile b/python/Makefile new file mode 100644 index 00000000000..6ffd68d8d37 --- /dev/null +++ b/python/Makefile @@ -0,0 +1,41 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = . + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = modules python + +ifneq ($(MAKECMDGOALS),install) +SUBDIRS := $(SUBDIRS) test +endif + +INSTALL_SUBDIRS = $(install_pythondir) $(install_libdir) + +install:: install-common + @for subdir in $(INSTALL_SUBDIRS); \ + do \ + if test ! -d $(DESTDIR)$$subdir ; \ + then \ + echo "Creating $(DESTDIR)$$subdir..." ; \ + mkdir -p $(DESTDIR)$$subdir ; \ + chmod a+rx $(DESTDIR)$$subdir ; \ + fi ; \ + done + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done + +test:: + @python $(top_srcdir)/allTests.py diff --git a/python/Makefile.mak b/python/Makefile.mak new file mode 100644 index 00000000000..052d2a10cf8 --- /dev/null +++ b/python/Makefile.mak @@ -0,0 +1,32 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = . + +!include $(top_srcdir)\config\Make.rules.mak + +SUBDIRS = modules python test + +install:: install-common + @if not exist "$(install_pythondir)" \ + @echo "Creating $(install_pythondir)..." && \ + mkdir "$(install_pythondir)" + +$(EVERYTHING_EXCEPT_INSTALL):: + @for %i in ( $(SUBDIRS) ) do \ + @echo "making $@ in %i" && \ + cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1 + +install:: + @for %i in ( modules python ) do \ + @echo "making $@ in %i" && \ + cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1 + +test:: + @python $(top_srcdir)/allTests.py diff --git a/python/allTests.py b/python/allTests.py new file mode 100755 index 00000000000..7ef76ff3f78 --- /dev/null +++ b/python/allTests.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, re, getopt + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +# +# List of all basic tests. +# +tests = [ + ("Slice/keyword", ["once"]), + ("Slice/structure", ["once"]), + ("Slice/macros", ["once"]), + ("Slice/import", ["once"]), + ("Ice/adapterDeactivation", ["core"]), + ("Ice/binding", ["core"]), + ("Ice/exceptions", ["core"]), + ("Ice/facets", ["core"]), + ("Ice/faultTolerance", ["core"]), + ("Ice/info", ["core", "noipv6", "nocompress"]), + ("Ice/inheritance", ["core"]), + ("Ice/location", ["core"]), + ("Ice/objects", ["core"]), + ("Ice/proxy", ["core"]), + ("Ice/properties", ["once"]), + ("Ice/operations", ["core"]), + ("Ice/slicing/exceptions", ["core"]), + ("Ice/slicing/objects", ["core"]), + ("Ice/custom", ["core"]), + ("Ice/checksum", ["core"]), + ("Ice/timeout", ["core", "nocompress"]), + ("Ice/servantLocator", ["core"]), + ("Ice/blobject", ["core"]), + ("Ice/defaultServant", ["core"]), + ("Ice/defaultValue", ["core"]), + ("Ice/ami", ["core", "nocompress"]), + ("Ice/optional", ["core"]), + ("Ice/enums", ["core"]), + ("Ice/acm", ["core"]) + ] + +if __name__ == "__main__": + TestUtil.run(tests) diff --git a/python/config/Make.rules b/python/config/Make.rules new file mode 100644 index 00000000000..64725d998c8 --- /dev/null +++ b/python/config/Make.rules @@ -0,0 +1,193 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +# +# Select an installation base directory. The directory will be created +# if it does not exist. +# +prefix ?= /opt/Ice-$(VERSION) + +# +# The "root directory" for runpath embedded in executables. Can be set +# to change the runpath added to Ice executables. The default is +# platform dependent. +# +#embedded_runpath_prefix ?= /opt/Ice-$(VERSION_MAJOR).$(VERSION_MINOR) + +# +# Define embedded_runpath as no if you don't want any RPATH added to +# the executables. +# +embedded_runpath ?= yes + +# +# Define OPTIMIZE as yes if you want to build with optimization. +# Otherwise the Ice extension is built with debug information. +# + +#OPTIMIZE = yes + +# +# Define LP64 as yes if you want to build in 64 bit mode on a platform +# that supports both 32 and 64 bit. +# +#LP64 := yes + +# +# The values below can be overridden by defining them as environment +# variables. +# + +# +# If multiple versions of Python are installed and you want a specific +# version used for building the Ice extension, then set PYTHON to +# the specific to the location of the python interpreter. +# +PYTHON ?= python + +PYTHON_VERSION ?= python$(shell $(PYTHON) -c "import sys; import distutils.sysconfig as ds; sys.stdout.write(ds.get_python_version())") + +PYTHON_BASE_VERSION ?= $(shell $(PYTHON) -c "import sys; import distutils.sysconfig as ds; sys.stdout.write(ds.get_python_version())") + +PYTHON_INCLUDE_DIR ?= $(shell $(PYTHON) -c "import sys; import distutils.sysconfig as ds; sys.stdout.write(ds.get_python_inc())") + +PYTHON_LIB_DIR ?= $(shell $(PYTHON) -c "import sys; import distutils.sysconfig as ds; sys.stdout.write(ds.get_config_var('LIBPL'))") + +PYTHON_LIB_SUFFIX ?= $(shell $(PYTHON) -c "import sys; sys.stdout.write(sys.__dict__['abiflags'] if 'abiflags' in sys.__dict__ else '')") + +PYTHON_LIB_NAME ?= $(PYTHON_VERSION)$(PYTHON_LIB_SUFFIX) + +PYTHON_FLAGS ?= -I$(PYTHON_INCLUDE_DIR) +PYTHON_LIBS ?= -L$(PYTHON_LIB_DIR) -l$(PYTHON_LIB_NAME) + +# +# The build architectures for gcc based builds. The format of these +# build flags are OS dependent. For example, under OS X to build +# binaries which support both i386 and x86_64 you would use "-arch +# i386 -arch x86_64". The default is OS version dependent. Be aware +# that this value may conflict with the setting of LP64 above. +# +#CXXARCHFLAGS = -arch i386 -arch x86_64 + +# ---------------------------------------------------------------------- +# Don't change anything below this line! +# ---------------------------------------------------------------------- + +# +# Common definitions +# +ice_language = python +ice_require_cpp = yes +slice_translator = slice2py + +ifeq ($(shell test -f $(top_srcdir)/config/Make.common.rules && echo 0),0) + include $(top_srcdir)/config/Make.common.rules +else + include $(top_srcdir)/../config/Make.common.rules +endif + +ifndef usr_dir_install +RPATH_DIR = $(prefix)/$(libsubdir) +endif + +# +# Platform specific definitions +# +ifeq ($(shell test -f $(top_srcdir)/config/Make.rules.$(UNAME) && echo 0),0) + include $(top_srcdir)/config/Make.rules.$(UNAME) +else + include $(top_srcdir)/../cpp/config/Make.rules.$(UNAME) +endif + +libdir = $(top_srcdir)/python + +ifndef usr_dir_install + install_pythondir = $(prefix)/python + install_libdir = $(prefix)/python +else + # + # The install_dir script says where python wants site-packages installed. + # + + install_pythondir = $(shell $(PYTHON) $(top_srcdir)/config/install_dir) + install_libdir = $(install_pythondir) +endif + +ifeq ($(UNAME),SunOS) + ifeq ($(LP64),yes) + libdir = $(top_srcdir)/python$(lp64suffix) + install_libdir = $(prefix)/python$(lp64suffix) + endif +endif + +ifdef ice_src_dist + ICE_LIB_DIR = -L$(ice_cpp_dir)/$(libsubdir) + ICE_FLAGS = -I$(ice_cpp_dir)/include +else + ICE_LIB_DIR = -L$(ice_dir)/$(libsubdir) + ICE_FLAGS = -I$(ice_dir)/include +endif +ICE_LIBS = $(ICE_LIB_DIR) -lIce -lSlice -lIceUtil + +CPPFLAGS = +ICECPPFLAGS = -I$(slicedir) +SLICE2PYFLAGS = $(ICECPPFLAGS) +LDFLAGS = $(LDPLATFORMFLAGS) $(CXXFLAGS) -L$(libdir) + +ifdef ice_src_dist + SLICE2PY = $(ice_cpp_dir)/bin/slice2py + SLICEPARSERLIB = $(ice_cpp_dir)/$(libsubdir)/$(call mklibfilename,Slice,$(VERSION)) + ifeq ($(wildcard $(SLICEPARSERLIB)),) + SLICEPARSERLIB = $(ice_cpp_dir)/$(lib64subdir)/$(call mklibfilename,Slice,$(VERSION)) + endif +else + SLICE2PY = $(ice_dir)/$(binsubdir)/slice2py + SLICEPARSERLIB = $(ice_dir)/$(libsubdir)/$(call mklibfilename,Slice,$(VERSION)) + ifeq ($(wildcard $(SLICEPARSERLIB)),) + SLICEPARSERLIB = $(ice_dir)/$(lib64subdir)/$(call mklibfilename,Slice,$(VERSION)) + endif +endif + +# +# A Python extension library cannot have a "lib" prefix, so Python-specific +# functions are defined that strip "lib" from the regular library name. +# +mkpylibfilename = $(subst dy,dylib,$(subst lib,,$(call mklibfilename,$(1),$(2)))) +mkpysoname = $(subst dy,dylib,$(subst lib,,$(call mksoname,$(1),$(2)))) +mkpylibname = $(subst dy,dylib,$(subst lib,,$(call mklibname,$(1)))) + +EVERYTHING = all depend clean install + +.SUFFIXES: +.SUFFIXES: .cpp .o .py + +all:: $(SRCS) + +%_ice.py: $(slicedir)/%.ice + rm -f $(*F).py + $(SLICE2PY) $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) $(SLICE2PYFLAGS) $< > .depend/$(*F).ice.d + +.cpp.o: + $(CXX) -c $(CPPFLAGS) $(CXXFLAGS) $< + @mkdir -p .depend + @$(CXX) -DMAKEDEPEND -M $(CPPFLAGS) $< > .depend/$(*F).d + +clean:: + -rm -f $(TARGETS) + -rm -f core *.o *.pyc *.bak + -rm -rf __pycache__ + -rm -rf .depend + +all:: $(SRCS) $(TARGETS) + +include $(wildcard .depend/*.d) + +install:: diff --git a/python/config/Make.rules.Darwin b/python/config/Make.rules.Darwin new file mode 100644 index 00000000000..426fe2ac12e --- /dev/null +++ b/python/config/Make.rules.Darwin @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +# +# This file is included by Make.rules when uname is Darwin. +# + +include $(top_srcdir)/../cpp/config/Make.rules.$(UNAME) + +shlibldflags += $(LDEXEFLAGS) + +mksoname = $(if $(2),lib$(1).$(2).so,lib$(1).so) +mklibname = lib$(1).so + +mkshlib = $(CXX) -dynamiclib $(shlibldflags) -o $(1) -install_name @rpath/$(2) $(3) $(4)
\ No newline at end of file diff --git a/python/config/Make.rules.Linux b/python/config/Make.rules.Linux new file mode 100644 index 00000000000..0690dd5e3e0 --- /dev/null +++ b/python/config/Make.rules.Linux @@ -0,0 +1,27 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +# +# This file is itself included by Make.rules +# + +include $(top_srcdir)/../cpp/config/Make.rules.$(UNAME) + +ifeq ($(CXX),g++) + ifeq ($(OPTIMIZE),yes) + # + # Necessary to avoid warnings for Python < 3.x + # + ifneq ($(findstring $(PYTHON_BASE_VERSION),2.6 2.7),) + CXXFLAGS += -fno-strict-aliasing + endif + endif +endif + +mkshlib = $(CXX) -shared $(LDFLAGS) $(LDEXEFLAGS) -o $(1) -Wl,-h,$(2) $(3) $(4) -lpthread
\ No newline at end of file diff --git a/python/config/Make.rules.mak b/python/config/Make.rules.mak new file mode 100644 index 00000000000..ecc3fecbc5c --- /dev/null +++ b/python/config/Make.rules.mak @@ -0,0 +1,156 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +# +# Select an installation base directory. The directory will be created +# if it does not exist. +# + +prefix = C:\Ice-$(VERSION) + +# +# Define OPTIMIZE as yes if you want to build with optimization. +# Otherwise the Ice extension is built with debug information. +# + +OPTIMIZE = yes + +# +# Specify your C++ compiler, or leave unset for auto-detection. The +# only value currently supported to build IcePy is VC100. +# +#CPP_COMPILER = VCxxx + +# +# Set PYTHON_HOME to your Python installation directory. +# +!if "$(PYTHON_HOME)" == "" +PYTHON_HOME = C:\Python34 +!endif + +# ---------------------------------------------------------------------- +# Don't change anything below this line! +# ---------------------------------------------------------------------- + +# +# Common definitions +# +ice_language = py +ice_require_cpp = yes +slice_translator = slice2py.exe + +!if exist ($(top_srcdir)\..\config\Make.common.rules.mak) +!include $(top_srcdir)\..\config\Make.common.rules.mak +!else +!include $(top_srcdir)\config\Make.common.rules.mak +!endif + +libdir = $(top_srcdir)\python +install_pythondir = $(prefix)\python$(x64suffix) +install_libdir = $(prefix)\python$(x64suffix) + +!include $(top_srcdir)\..\cpp\config\Make.rules.msvc + +libsuff = $(x64suffix) + +!if "$(OPTIMIZE)" != "yes" +LIBSUFFIX = $(LIBSUFFIX)d +PYLIBSUFFIX = _$(LIBSUFFIX) +RCFLAGS = -D_DEBUG +!endif + +# +# Import libraries are located automatically +# +ICE_LIBS = + +!if "$(ice_src_dist)" != "" +ICE_CPPFLAGS = -I"$(ice_cpp_dir)\include" +!if "$(ice_cpp_dir)" == "$(ice_dir)\cpp" +ICE_LDFLAGS = /LIBPATH:"$(ice_cpp_dir)\lib" +!else +ICE_LDFLAGS = /LIBPATH:"$(ice_cpp_dir)\lib$(libsuff)" +!endif +!else +ICE_CPPFLAGS = -I"$(ice_dir)\include" +ICE_LDFLAGS = /LIBPATH:"$(ice_dir)\lib$(libsuff)" +!endif + +slicedir = $(ice_dir)\slice + +PYTHON_CPPFLAGS = -I"$(PYTHON_HOME)\include" +PYTHON_LDFLAGS = /LIBPATH:"$(PYTHON_HOME)\libs" + +ICECPPFLAGS = -I"$(slicedir)" +SLICE2PYFLAGS = $(ICECPPFLAGS) + +!if "$(ice_src_dist)" != "" +!if "$(ice_cpp_dir)" == "$(ice_dir)\cpp" +SLICE2PY = $(ice_cpp_dir)\bin\slice2py.exe +SLICEPARSERLIB = $(ice_cpp_dir)\lib\slice.lib +!if !exist ("$(SLICEPARSERLIB)") +SLICEPARSERLIB = $(ice_cpp_dir)\lib\sliced.lib +!endif +!else +SLICE2PY = $(ice_cpp_dir)\bin$(x64suffix)\slice2py.exe +SLICEPARSERLIB = $(ice_cpp_dir)\lib$(x64suffix)\slice.lib +!if !exist ("$(SLICEPARSERLIB)") +SLICEPARSERLIB = $(ice_cpp_dir)\lib$(x64suffix)\sliced.lib +!endif +!endif +!else +SLICE2PY = $(ice_dir)\bin\slice2py.exe +SLICEPARSERLIB = $(ice_dir)\lib\slice.lib +!endif + +MT = mt.exe + +EVERYTHING = all clean install depend +EVERYTHING_EXCEPT_INSTALL = all clean depend + +.SUFFIXES: +.SUFFIXES: .cpp .obj .py .res .rc .d .ice + +DEPEND_DIR = .depend.mak + +depend:: + +!if exist(.depend.mak) +!include .depend.mak +!endif + +!if "$(OBJS)" != "" +depend:: + @del /q .depend.mak + +OBJS_DEPEND = $(OBJS:.obj=.d) +OBJS_DEPEND = $(OBJS_DEPEND:.\=.depend.mak\) + +depend:: $(OBJS_DEPEND) + +!endif + +.cpp{$(DEPEND_DIR)}.d: + @echo Generating dependencies for $< + @$(CXX) /E $(CPPFLAGS) $(CXXFLAGS) /showIncludes $< 1>$(*F).i 2>$(*F).d && \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend.vbs $(*F).cpp $(top_srcdir) + @del /q $(*F).d $(*F).i + +.cpp.obj:: + $(CXX) /c $(CPPFLAGS) $(CXXFLAGS) $< + +.rc.res: + rc $(RCFLAGS) $< + +clean:: + del /q $(TARGETS) *.obj *.pyc *.bak + +all:: $(SRCS) $(TARGETS) + +install:: diff --git a/python/config/install_dir b/python/config/install_dir new file mode 100644 index 00000000000..8bb2e0c62f5 --- /dev/null +++ b/python/config/install_dir @@ -0,0 +1,35 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2014 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +from setuptools.command.easy_install import easy_install +class easy_install_default(easy_install): + """ class easy_install had problems with the fist parameter not being + an instance of Distribution, even though it was. This is due to + some import-related mess. + """ + + def __init__(self): + from distutils.dist import Distribution + dist = Distribution() + self.distribution = dist + self.initialize_options() + self._dry_run = None + self.verbose = dist.verbose + self.force = None + self.help = 0 + self.finalized = 0 + +e = easy_install_default() +import distutils.errors +try: + e.finalize_options() +except distutils.errors.DistutilsError: + pass + +print e.install_dir diff --git a/python/modules/IcePy/.depend.mak b/python/modules/IcePy/.depend.mak new file mode 100644 index 00000000000..f4834457aa7 --- /dev/null +++ b/python/modules/IcePy/.depend.mak @@ -0,0 +1,1550 @@ + +BatchRequestInterceptor.obj: \ + BatchRequestInterceptor.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "BatchRequestInterceptor.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Thread.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + +Communicator.obj: \ + Communicator.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "$(ice_cpp_dir)\include\IceUtil\DisableWarnings.h" \ + "Communicator.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "BatchRequestInterceptor.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "ImplicitContext.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContext.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "Logger.h" \ + "$(ice_cpp_dir)\include\Ice\Logger.h" \ + "ObjectAdapter.h" \ + "ObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactory.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "Operation.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "Properties.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "Proxy.h" \ + "Thread.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorAsync.h" \ + "$(ice_cpp_dir)\include\Ice\Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\RouterF.h" \ + "$(ice_cpp_dir)\include\Ice\LocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PluginF.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContextF.h" \ + "$(ice_cpp_dir)\include\Ice\Properties.h" \ + "$(ice_cpp_dir)\include\Ice\FacetMap.h" \ + "$(ice_cpp_dir)\include\Ice\Locator.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \ + "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ProcessF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\Router.h" \ + +Connection.obj: \ + Connection.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Connection.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Communicator.h" \ + "ConnectionInfo.h" \ + "$(ice_cpp_dir)\include\Ice\Connection.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "Endpoint.h" \ + "ObjectAdapter.h" \ + "Operation.h" \ + "Proxy.h" \ + "Thread.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionAsync.h" \ + +ConnectionInfo.obj: \ + ConnectionInfo.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "ConnectionInfo.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\Connection.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "EndpointInfo.h" \ + "Util.h" \ + +Current.obj: \ + Current.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Current.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "Connection.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "ObjectAdapter.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\LocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\FacetMap.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + +Endpoint.obj: \ + Endpoint.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Endpoint.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "EndpointInfo.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + +EndpointInfo.obj: \ + EndpointInfo.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "EndpointInfo.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + +ImplicitContext.obj: \ + ImplicitContext.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "ImplicitContext.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContext.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "ObjectAdapter.h" \ + "Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Util.h" \ + +Init.obj: \ + Init.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "BatchRequestInterceptor.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Connection.h" \ + "ConnectionInfo.h" \ + "$(ice_cpp_dir)\include\Ice\Connection.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "Current.h" \ + "Endpoint.h" \ + "EndpointInfo.h" \ + "ImplicitContext.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContext.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "Logger.h" \ + "$(ice_cpp_dir)\include\Ice\Logger.h" \ + "ObjectAdapter.h" \ + "Operation.h" \ + "Properties.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "Proxy.h" \ + "Slice.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + +Logger.obj: \ + Logger.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Logger.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\Logger.h" \ + "Thread.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + +ObjectAdapter.obj: \ + ObjectAdapter.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "ObjectAdapter.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Current.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "Operation.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "Proxy.h" \ + "Thread.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "$(ice_cpp_dir)\include\Ice\RouterF.h" \ + "$(ice_cpp_dir)\include\Ice\LocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PluginF.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContextF.h" \ + "$(ice_cpp_dir)\include\Ice\Properties.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\FacetMap.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\Locator.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \ + "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ProcessF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \ + "$(ice_cpp_dir)\include\Ice\Router.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocator.h" \ + +ObjectFactory.obj: \ + ObjectFactory.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "ObjectFactory.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactory.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "Thread.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + +Operation.obj: \ + Operation.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Operation.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "Communicator.h" \ + "Current.h" \ + "Proxy.h" \ + "Thread.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "Connection.h" \ + "$(ice_cpp_dir)\include\Ice\Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "$(ice_cpp_dir)\include\Ice\RouterF.h" \ + "$(ice_cpp_dir)\include\Ice\LocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PluginF.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContextF.h" \ + "$(ice_cpp_dir)\include\Ice\Properties.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\FacetMap.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\Logger.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapter.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Slice\PythonUtil.h" \ + "$(ice_cpp_dir)\include\Slice\Parser.h" \ + +Properties.obj: \ + Properties.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Properties.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "$(ice_cpp_dir)\include\Ice\Properties.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + +PropertiesAdmin.obj: \ + PropertiesAdmin.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "$(ice_cpp_dir)\include\IceUtil\DisableWarnings.h" \ + "PropertiesAdmin.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\NativePropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "Util.h" \ + "Thread.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "Types.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + +Proxy.obj: \ + Proxy.cpp \ + "$(ice_cpp_dir)\include\IceUtil\DisableWarnings.h" \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Proxy.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "Communicator.h" \ + "Connection.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\Endpoint.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "Operation.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "Thread.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "$(ice_cpp_dir)\include\Ice\Communicator.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + "$(ice_cpp_dir)\include\Ice\Incoming.h" \ + "$(ice_cpp_dir)\include\Ice\ServantLocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\ServantManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\ResponseHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsync.h" \ + "$(ice_cpp_dir)\include\Ice\RouterF.h" \ + "$(ice_cpp_dir)\include\Ice\LocatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PluginF.h" \ + "$(ice_cpp_dir)\include\Ice\ImplicitContextF.h" \ + "$(ice_cpp_dir)\include\Ice\Properties.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesAdmin.h" \ + "$(ice_cpp_dir)\include\Ice\FacetMap.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\Locator.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTableInit.h" \ + "$(ice_cpp_dir)\include\Ice\DefaultObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactory.h" \ + "$(ice_cpp_dir)\include\Ice\ProcessF.h" \ + "$(ice_cpp_dir)\include\Ice\Router.h" \ + +Slice.obj: \ + Slice.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Slice.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Slice\Preprocessor.h" \ + "$(ice_cpp_dir)\include\Slice\PythonUtil.h" \ + "$(ice_cpp_dir)\include\Slice\Parser.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "$(ice_cpp_dir)\include\Slice\Util.h" \ + "$(ice_cpp_dir)\include\IceUtil\Options.h" \ + "$(ice_cpp_dir)\include\IceUtil\RecMutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + +Thread.obj: \ + Thread.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Thread.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + +Types.obj: \ + Types.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Types.h" \ + "Config.h" \ + "Util.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\Ice\Stream.h" \ + "$(ice_cpp_dir)\include\Ice\CommunicatorF.h" \ + "$(ice_cpp_dir)\include\Ice\Object.h" \ + "$(ice_cpp_dir)\include\IceUtil\Mutex.h" \ + "$(ice_cpp_dir)\include\IceUtil\Lock.h" \ + "$(ice_cpp_dir)\include\IceUtil\ThreadException.h" \ + "$(ice_cpp_dir)\include\IceUtil\Time.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexProtocol.h" \ + "$(ice_cpp_dir)\include\Ice\IncomingAsyncF.h" \ + "$(ice_cpp_dir)\include\Ice\Proxy.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionIF.h" \ + "$(ice_cpp_dir)\include\Ice\RequestHandlerF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointF.h" \ + "$(ice_cpp_dir)\include\Ice\EndpointTypes.h" \ + "$(ice_cpp_dir)\include\Ice\ReferenceF.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestQueueF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResult.h" \ + "$(ice_cpp_dir)\include\IceUtil\Monitor.h" \ + "$(ice_cpp_dir)\include\IceUtil\Cond.h" \ + "$(ice_cpp_dir)\include\IceUtil\UniquePtr.h" \ + "$(ice_cpp_dir)\include\Ice\InstanceF.h" \ + "$(ice_cpp_dir)\include\Ice\AsyncResultF.h" \ + "$(ice_cpp_dir)\include\Ice\ObserverHelper.h" \ + "$(ice_cpp_dir)\include\Ice\Instrumentation.h" \ + "$(ice_cpp_dir)\include\Ice\BasicStream.h" \ + "$(ice_cpp_dir)\include\IceUtil\StringConverter.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryF.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectFactoryManagerF.h" \ + "$(ice_cpp_dir)\include\Ice\Buffer.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedDataF.h" \ + "$(ice_cpp_dir)\include\Ice\UserExceptionFactory.h" \ + "$(ice_cpp_dir)\include\Ice\FactoryTable.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ + "Current.h" \ + "Proxy.h" \ + "Thread.h" \ + "$(ice_cpp_dir)\include\Ice\Initialize.h" \ + "$(ice_cpp_dir)\include\IceUtil\Timer.h" \ + "$(ice_cpp_dir)\include\IceUtil\Thread.h" \ + "$(ice_cpp_dir)\include\Ice\PropertiesF.h" \ + "$(ice_cpp_dir)\include\Ice\LoggerF.h" \ + "$(ice_cpp_dir)\include\Ice\InstrumentationF.h" \ + "$(ice_cpp_dir)\include\Ice\Dispatcher.h" \ + "$(ice_cpp_dir)\include\Ice\Plugin.h" \ + "$(ice_cpp_dir)\include\Ice\BatchRequestInterceptor.h" \ + "$(ice_cpp_dir)\include\IceUtil\InputUtil.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\SlicedData.h" \ + "$(ice_cpp_dir)\include\Ice\GCObject.h" \ + "$(ice_cpp_dir)\include\IceUtil\MutexPtrLock.h" \ + +Util.obj: \ + Util.cpp \ + "$(ice_cpp_dir)\include\IceUtil\Config.h" \ + "Util.h" \ + "Config.h" \ + "$(ice_cpp_dir)\include\Ice\BuiltinSequences.h" \ + "$(ice_cpp_dir)\include\IceUtil\PushDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyF.h" \ + "$(ice_cpp_dir)\include\IceUtil\Shared.h" \ + "$(ice_cpp_dir)\include\IceUtil\Atomic.h" \ + "$(ice_cpp_dir)\include\Ice\Config.h" \ + "$(ice_cpp_dir)\include\Ice\ProxyHandle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Handle.h" \ + "$(ice_cpp_dir)\include\IceUtil\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\Handle.h" \ + "$(ice_cpp_dir)\include\Ice\Exception.h" \ + "$(ice_cpp_dir)\include\Ice\Format.h" \ + "$(ice_cpp_dir)\include\Ice\StreamF.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObject.h" \ + "$(ice_cpp_dir)\include\Ice\LocalObjectF.h" \ + "$(ice_cpp_dir)\include\Ice\StreamHelpers.h" \ + "$(ice_cpp_dir)\include\IceUtil\ScopedArray.h" \ + "$(ice_cpp_dir)\include\IceUtil\Iterator.h" \ + "$(ice_cpp_dir)\include\IceUtil\Optional.h" \ + "$(ice_cpp_dir)\include\IceUtil\UndefSysMacros.h" \ + "$(ice_cpp_dir)\include\IceUtil\PopDisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\Current.h" \ + "$(ice_cpp_dir)\include\Ice\ObjectAdapterF.h" \ + "$(ice_cpp_dir)\include\Ice\ConnectionF.h" \ + "$(ice_cpp_dir)\include\Ice\Identity.h" \ + "$(ice_cpp_dir)\include\Ice\Version.h" \ + "$(ice_cpp_dir)\include\IceUtil\DisableWarnings.h" \ + "$(ice_cpp_dir)\include\Ice\LocalException.h" \ + "$(ice_cpp_dir)\include\Ice\Protocol.h" \ + "$(ice_cpp_dir)\include\IceUtil\UUID.h" \ + "$(ice_cpp_dir)\include\Slice\PythonUtil.h" \ + "$(ice_cpp_dir)\include\Slice\Parser.h" \ + "$(ice_cpp_dir)\include\IceUtil\OutputUtil.h" \ diff --git a/python/modules/IcePy/BatchRequestInterceptor.cpp b/python/modules/IcePy/BatchRequestInterceptor.cpp new file mode 100644 index 00000000000..d2a16905267 --- /dev/null +++ b/python/modules/IcePy/BatchRequestInterceptor.cpp @@ -0,0 +1,264 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <BatchRequestInterceptor.h> +#include <Proxy.h> +#include <Thread.h> +#include <Ice/Initialize.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct BatchRequestObject +{ + PyObject_HEAD + const Ice::BatchRequest* request; + PyObject* size; + PyObject* operation; + PyObject* proxy; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static BatchRequestObject* +batchRequestNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("Batch requests can only be created by the Ice runtime")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +batchRequestDealloc(BatchRequestObject* self) +{ + Py_XDECREF(self->size); + Py_XDECREF(self->operation); + Py_XDECREF(self->proxy); + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +batchRequestGetSize(BatchRequestObject* self) +{ + assert(self->request); + if(!self->size) + { + Ice::Int size; + try + { + size = self->request->getSize(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + self->size = PyLong_FromLong(size); + } + Py_INCREF(self->size); + return self->size; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +batchRequestGetOperation(BatchRequestObject* self) +{ + assert(self->request); + if(!self->operation) + { + string operation; + try + { + operation = self->request->getOperation(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + self->operation = createString(operation); + } + Py_INCREF(self->operation); + return self->operation; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +batchRequestGetProxy(BatchRequestObject* self) +{ + assert(self->request); + if(!self->proxy) + { + Ice::ObjectPrx proxy; + try + { + proxy = self->request->getProxy(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + self->proxy = createProxy(proxy, proxy->ice_getCommunicator()); + } + Py_INCREF(self->proxy); + return self->proxy; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +batchRequestEnqueue(BatchRequestObject* self) +{ + assert(self->request); + + try + { + self->request->enqueue(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef BatchRequestMethods[] = +{ + { STRCAST("getSize"), reinterpret_cast<PyCFunction>(batchRequestGetSize), METH_NOARGS, + PyDoc_STR(STRCAST("getSize() -> int")) }, + { STRCAST("getOperation"), reinterpret_cast<PyCFunction>(batchRequestGetOperation), METH_NOARGS, + PyDoc_STR(STRCAST("getOperation() -> string")) }, + { STRCAST("getProxy"), reinterpret_cast<PyCFunction>(batchRequestGetProxy), METH_NOARGS, + PyDoc_STR(STRCAST("getProxy() -> Ice.ObjectPrx")) }, + { STRCAST("enqueue"), reinterpret_cast<PyCFunction>(batchRequestEnqueue), METH_NOARGS, + PyDoc_STR(STRCAST("enqueue() -> None")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject BatchRequestType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.BatchRequest"), /* tp_name */ + sizeof(BatchRequestObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(batchRequestDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + BatchRequestMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(batchRequestNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initBatchRequest(PyObject* module) +{ + if(PyType_Ready(&BatchRequestType) < 0) + { + return false; + } + PyTypeObject* type = &BatchRequestType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("BatchRequest"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +IcePy::BatchRequestInterceptor::BatchRequestInterceptor(PyObject* interceptor) : _interceptor(interceptor) +{ + Py_INCREF(interceptor); +} + +void +IcePy::BatchRequestInterceptor::enqueue(const Ice::BatchRequest& request, int queueCount, int queueSize) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + BatchRequestObject* obj = reinterpret_cast<BatchRequestObject*>(BatchRequestType.tp_alloc(&BatchRequestType, 0)); + if(!obj) + { + return; + } + + obj->request = &request; + obj->size = 0; + obj->operation = 0; + obj->proxy = 0; + PyObjectHandle tmp = PyObject_CallMethod(_interceptor.get(), STRCAST("enqueue"), STRCAST("Oii"), obj, queueCount, + queueSize); + if(!tmp.get()) + { + throwPythonException(); + } +} diff --git a/python/modules/IcePy/BatchRequestInterceptor.h b/python/modules/IcePy/BatchRequestInterceptor.h new file mode 100644 index 00000000000..53491ab7cb3 --- /dev/null +++ b/python/modules/IcePy/BatchRequestInterceptor.h @@ -0,0 +1,40 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_BATCH_REQUEST_INTERCEPTOR_H +#define ICEPY_BATCH_REQUEST_INTERCEPTOR_H + +#include <Config.h> +#include <Util.h> +#include <Ice/BatchRequestInterceptor.h> + +namespace IcePy +{ + +extern PyTypeObject BatchRequestType; + +bool initBatchRequest(PyObject*); + +class BatchRequestInterceptor : public Ice::BatchRequestInterceptor +{ +public: + + BatchRequestInterceptor(PyObject*); + + virtual void enqueue(const Ice::BatchRequest&, int, int); + +private: + + PyObjectHandle _interceptor; +}; +typedef IceUtil::Handle<BatchRequestInterceptor> BatchRequestInterceptorPtr; + +} + +#endif diff --git a/python/modules/IcePy/Communicator.cpp b/python/modules/IcePy/Communicator.cpp new file mode 100644 index 00000000000..919086d9ae8 --- /dev/null +++ b/python/modules/IcePy/Communicator.cpp @@ -0,0 +1,1717 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <IceUtil/DisableWarnings.h> +#include <Communicator.h> +#include <BatchRequestInterceptor.h> +#include <ImplicitContext.h> +#include <Logger.h> +#include <ObjectAdapter.h> +#include <ObjectFactory.h> +#include <Operation.h> +#include <Properties.h> +#include <PropertiesAdmin.h> +#include <Proxy.h> +#include <Thread.h> +#include <Types.h> +#include <Util.h> +#include <Ice/Initialize.h> +#include <Ice/CommunicatorAsync.h> +#include <Ice/LocalException.h> +#include <Ice/Locator.h> +#include <Ice/ObjectAdapter.h> +#include <Ice/Properties.h> +#include <Ice/Router.h> + +#include <pythread.h> + +using namespace std; +using namespace IcePy; + +static long _mainThreadId; + +typedef map<Ice::CommunicatorPtr, PyObject*> CommunicatorMap; +static CommunicatorMap _communicatorMap; + +namespace IcePy +{ + +struct CommunicatorObject; + +typedef InvokeThread<Ice::Communicator> WaitForShutdownThread; +typedef IceUtil::Handle<WaitForShutdownThread> WaitForShutdownThreadPtr; + +struct CommunicatorObject +{ + PyObject_HEAD + Ice::CommunicatorPtr* communicator; + PyObject* wrapper; + IceUtil::Monitor<IceUtil::Mutex>* shutdownMonitor; + WaitForShutdownThreadPtr* shutdownThread; + bool shutdown; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static CommunicatorObject* +communicatorNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + assert(type && type->tp_alloc); + CommunicatorObject* self = reinterpret_cast<CommunicatorObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->communicator = 0; + self->wrapper = 0; + self->shutdownMonitor = new IceUtil::Monitor<IceUtil::Mutex>; + self->shutdownThread = 0; + self->shutdown = false; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static int +communicatorInit(CommunicatorObject* self, PyObject* args, PyObject* /*kwds*/) +{ + PyObject* argList = 0; + PyObject* initData = 0; + if(!PyArg_ParseTuple(args, STRCAST("|OO"), &argList, &initData)) + { + return -1; + } + + if(argList == Py_None) + { + argList = 0; + } + + if(initData == Py_None) + { + initData = 0; + } + + PyObject* initDataType = lookupType("Ice.InitializationData"); + + if(argList && !initData) + { + if(PyObject_IsInstance(argList, initDataType)) + { + initData = argList; + argList = 0; + } + else if(!PyList_Check(argList)) + { + PyErr_Format(PyExc_ValueError, STRCAST("initialize expects an argument list or Ice.InitializationData")); + return -1; + } + } + else if(argList && initData) + { + if(!PyList_Check(argList) || !PyObject_IsInstance(initData, initDataType)) + { + PyErr_Format(PyExc_ValueError, STRCAST("initialize expects an argument list and Ice.InitializationData")); + return -1; + } + } + + Ice::StringSeq seq; + if(argList && !listToStringSeq(argList, seq)) + { + return -1; + } + + // + // Use the with-args or the without-args version of initialize()? + // + bool hasArgs = argList != 0; + + Ice::InitializationData data; + if(initData) + { + PyObjectHandle properties = PyObject_GetAttrString(initData, STRCAST("properties")); + PyObjectHandle logger = PyObject_GetAttrString(initData, STRCAST("logger")); + PyObjectHandle threadHook = PyObject_GetAttrString(initData, STRCAST("threadHook")); + PyObjectHandle batchRequestInterceptor = PyObject_GetAttrString(initData, STRCAST("batchRequestInterceptor")); + PyErr_Clear(); // PyObject_GetAttrString sets an error on failure. + + if(properties.get() && properties.get() != Py_None) + { + // + // Get the properties implementation. + // + PyObjectHandle impl = PyObject_GetAttrString(properties.get(), STRCAST("_impl")); + assert(impl.get()); + data.properties = getProperties(impl.get()); + } + + if(logger.get() && logger.get() != Py_None) + { + data.logger = new LoggerWrapper(logger.get()); + } + + if(threadHook.get() && threadHook.get() != Py_None) + { + data.threadHook = new ThreadHook(threadHook.get()); + } + + if(batchRequestInterceptor.get() && batchRequestInterceptor.get() != Py_None) + { + data.batchRequestInterceptor = new BatchRequestInterceptor(batchRequestInterceptor.get()); + } + } + + try + { + if(argList) + { + data.properties = Ice::createProperties(seq, data.properties); + } + else if(!data.properties) + { + data.properties = Ice::createProperties(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return -1; + } + + // + // Remaining command line options are passed to the communicator + // as an argument vector in case they contain plug-in properties. + // + int argc = static_cast<int>(seq.size()); + char** argv = new char*[argc + 1]; + int i = 0; + for(Ice::StringSeq::const_iterator s = seq.begin(); s != seq.end(); ++s, ++i) + { + argv[i] = strdup(s->c_str()); + } + argv[argc] = 0; + + data.compactIdResolver = new IdResolver; + + Ice::CommunicatorPtr communicator; + try + { + AllowThreads allowThreads; + if(hasArgs) + { + communicator = Ice::initialize(argc, argv, data); + } + else + { + communicator = Ice::initialize(data); + } + } + catch(const Ice::Exception& ex) + { + for(i = 0; i < argc; ++i) + { + free(argv[i]); + } + delete[] argv; + + setPythonException(ex); + return -1; + } + + // + // Replace the contents of the given argument list with the filtered arguments. + // + if(argList) + { + PyList_SetSlice(argList, 0, PyList_Size(argList), 0); // Clear the list. + + for(i = 0; i < argc; ++i) + { + PyObjectHandle str = Py_BuildValue(STRCAST("s"), argv[i]); + PyList_Append(argList, str.get()); + } + } + + for(i = 0; i < argc; ++i) + { + free(argv[i]); + } + delete[] argv; + + self->communicator = new Ice::CommunicatorPtr(communicator); + ObjectFactoryPtr factory = new ObjectFactory; + (*self->communicator)->addObjectFactory(factory, ""); + + CommunicatorMap::iterator p = _communicatorMap.find(communicator); + if(p != _communicatorMap.end()) + { + _communicatorMap.erase(p); + } + _communicatorMap.insert(CommunicatorMap::value_type(communicator, reinterpret_cast<PyObject*>(self))); + + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +communicatorDealloc(CommunicatorObject* self) +{ + if(self->communicator) + { + CommunicatorMap::iterator p = _communicatorMap.find(*self->communicator); + // + // find() can fail if an error occurred during communicator initialization. + // + if(p != _communicatorMap.end()) + { + _communicatorMap.erase(p); + } + } + + if(self->shutdownThread) + { + (*self->shutdownThread)->getThreadControl().join(); + } + delete self->communicator; + delete self->shutdownMonitor; + delete self->shutdownThread; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorDestroy(CommunicatorObject* self) +{ + assert(self->communicator); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock. + (*self->communicator)->destroy(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + // + // Break cyclic reference between this object and its Python wrapper. + // + Py_XDECREF(self->wrapper); + self->wrapper = 0; + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorShutdown(CommunicatorObject* self) +{ + assert(self->communicator); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock. + (*self->communicator)->shutdown(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorWaitForShutdown(CommunicatorObject* self, PyObject* args) +{ + // + // This method differs somewhat from the standard Ice API because of + // signal issues. This method expects an integer timeout value, and + // returns a boolean to indicate whether it was successful. When + // called from the main thread, the timeout is used to allow control + // to return to the caller (the Python interpreter) periodically. + // When called from any other thread, we call waitForShutdown directly + // and ignore the timeout. + // + int timeout = 0; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(timeout > 0); + assert(self->communicator); + + // + // Do not call waitForShutdown from the main thread, because it prevents + // signals (such as keyboard interrupts) from being delivered to Python. + // + if(PyThread_get_thread_ident() == _mainThreadId) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*self->shutdownMonitor); + + if(!self->shutdown) + { + if(self->shutdownThread == 0) + { + WaitForShutdownThreadPtr t = new WaitForShutdownThread(*self->communicator, + &Ice::Communicator::waitForShutdown, + *self->shutdownMonitor, self->shutdown); + self->shutdownThread = new WaitForShutdownThreadPtr(t); + t->start(); + } + + while(!self->shutdown) + { + bool done; + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + done = (*self->shutdownMonitor).timedWait(IceUtil::Time::milliSeconds(timeout)); + } + + if(!done) + { + PyRETURN_FALSE; + } + } + } + + assert(self->shutdown); + + Ice::Exception* ex = (*self->shutdownThread)->getException(); + if(ex) + { + setPythonException(*ex); + return 0; + } + } + else + { + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->communicator)->waitForShutdown(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + } + + PyRETURN_TRUE; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorIsShutdown(CommunicatorObject* self) +{ + assert(self->communicator); + bool isShutdown; + try + { + isShutdown = (*self->communicator)->isShutdown(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyRETURN_BOOL(isShutdown); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorStringToProxy(CommunicatorObject* self, PyObject* args) +{ + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj)) + { + return 0; + } + + string str; + if(!getStringArg(strObj, "str", str)) + { + return 0; + } + + assert(self->communicator); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->communicator)->stringToProxy(str); + if(proxy) + { + return createProxy(proxy, *self->communicator); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorProxyToString(CommunicatorObject* self, PyObject* args) +{ + PyObject* obj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &obj)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(obj, "proxyToString", "obj", proxy)) + { + return 0; + } + + string str; + + assert(self->communicator); + try + { + str = (*self->communicator)->proxyToString(proxy); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(str); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorPropertyToProxy(CommunicatorObject* self, PyObject* args) +{ + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj)) + { + return 0; + } + + string str; + if(!getStringArg(strObj, "property", str)) + { + return 0; + } + + assert(self->communicator); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->communicator)->propertyToProxy(str); + if(proxy) + { + return createProxy(proxy, *self->communicator); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorProxyToProperty(CommunicatorObject* self, PyObject* args) +{ + // + // We don't want to accept None here, so we can specify ProxyType and force + // the caller to supply a proxy object. + // + PyObject* proxyObj; + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), &ProxyType, &proxyObj, &strObj)) + { + return 0; + } + + Ice::ObjectPrx proxy = getProxy(proxyObj); + string str; + if(!getStringArg(strObj, "property", str)) + { + return 0; + } + + assert(self->communicator); + Ice::PropertyDict dict; + try + { + dict = (*self->communicator)->proxyToProperty(proxy, str); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(result.get()) + { + for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + PyObjectHandle key = createString(p->first); + PyObjectHandle val = createString(p->second); + if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) + { + return 0; + } + } + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorStringToIdentity(CommunicatorObject* self, PyObject* args) +{ + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj)) + { + return 0; + } + + string str; + if(!getStringArg(strObj, "str", str)) + { + return 0; + } + + assert(self->communicator); + Ice::Identity id; + try + { + id = (*self->communicator)->stringToIdentity(str); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createIdentity(id); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorIdentityToString(CommunicatorObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* obj; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &obj)) + { + return 0; + } + + Ice::Identity id; + if(!getIdentity(obj, id)) + { + return 0; + } + string str; + + assert(self->communicator); + try + { + str = (*self->communicator)->identityToString(id); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(str); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorFlushBatchRequests(CommunicatorObject* self) +{ + assert(self->communicator); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock. + (*self->communicator)->flushBatchRequests(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorBeginFlushBatchRequests(CommunicatorObject* self, PyObject* args, PyObject* kwds) +{ + assert(self->communicator); + + static char* argNames[] = + { + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + 0 + }; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &ex, &sent)) + { + return 0; + } + + if(ex == Py_None) + { + ex = 0; + } + if(sent == Py_None) + { + sent = 0; + } + + if(!ex && sent) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("exception callback must also be provided when sent callback is used")); + return 0; + } + + Ice::Callback_Communicator_flushBatchRequestsPtr cb; + if(ex || sent) + { + FlushCallbackPtr d = new FlushCallback(ex, sent, "flushBatchRequests"); + cb = Ice::newCallback_Communicator_flushBatchRequests(d, &FlushCallback::exception, &FlushCallback::sent); + } + + Ice::AsyncResultPtr result; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + + if(cb) + { + result = (*self->communicator)->begin_flushBatchRequests(cb); + } + else + { + result = (*self->communicator)->begin_flushBatchRequests(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createAsyncResult(result, 0, 0, self->wrapper); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorEndFlushBatchRequests(CommunicatorObject* self, PyObject* args) +{ + assert(self->communicator); + + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + Ice::AsyncResultPtr r = getAsyncResult(result); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->communicator)->end_flushBatchRequests(r); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorCreateAdmin(CommunicatorObject* self, PyObject* args) +{ + PyObject* adapter; + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("OO!"), &adapter, identityType, &id)) + { + return 0; + } + + Ice::ObjectAdapterPtr oa; + + PyObject* adapterType = lookupType("Ice.ObjectAdapter"); + if(adapter != Py_None && !PyObject_IsInstance(adapter, adapterType)) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected ObjectAdapter or None")); + return 0; + } + + if(adapter != Py_None) + { + oa = unwrapObjectAdapter(adapter); + } + + Ice::Identity identity; + if(!getIdentity(id, identity)) + { + return 0; + } + + assert(self->communicator); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->communicator)->createAdmin(oa, identity); + assert(proxy); + + return createProxy(proxy, *self->communicator); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetAdmin(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->communicator)->getAdmin(); + if(proxy) + { + return createProxy(proxy, *self->communicator); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorAddAdminFacet(CommunicatorObject* self, PyObject* args) +{ + PyObject* objectType = lookupType("Ice.Object"); + PyObject* servant; + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), objectType, &servant, &facetObj)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + ServantWrapperPtr wrapper = createServantWrapper(servant); + if(PyErr_Occurred()) + { + return 0; + } + + assert(self->communicator); + try + { + (*self->communicator)->addAdminFacet(wrapper, facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorFindAdminFacet(CommunicatorObject* self, PyObject* args) +{ + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &facetObj)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->communicator); + try + { + // + // The facet being found may not be implemented by a Python servant + // (e.g., it could be the Process or Properties facet), in which case + // we return None. + // + Ice::ObjectPtr obj = (*self->communicator)->findAdminFacet(facet); + if(obj) + { + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + if(wrapper) + { + return wrapper->getObject(); + } + + Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(obj); + if(props) + { + return createNativePropertiesAdmin(props); + } + + // If the facet isn't supported in Python, just return an Ice.Object. + PyTypeObject* objectType = reinterpret_cast<PyTypeObject*>(lookupType("Ice.Object")); + return objectType->tp_alloc(objectType, 0); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorFindAllAdminFacets(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::FacetMap facetMap; + try + { + facetMap = (*self->communicator)->findAllAdminFacets(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(!result.get()) + { + return 0; + } + + PyTypeObject* objectType = reinterpret_cast<PyTypeObject*>(lookupType("Ice.Object")); + PyObjectHandle plainObject = objectType->tp_alloc(objectType, 0); + + + for(Ice::FacetMap::const_iterator p = facetMap.begin(); p != facetMap.end(); ++p) + { + + PyObjectHandle obj = plainObject; + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(p->second); + if(wrapper) + { + obj = wrapper->getObject(); + } + else + { + Ice::NativePropertiesAdminPtr props = Ice::NativePropertiesAdminPtr::dynamicCast(p->second); + if(props) + { + obj = createNativePropertiesAdmin(props); + } + } + + if(PyDict_SetItemString(result.get(), const_cast<char*>(p->first.c_str()), obj.get()) < 0) + { + return 0; + } + } + + return result.release(); +} + + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorRemoveAdminFacet(CommunicatorObject* self, PyObject* args) +{ + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &facetObj)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->communicator); + try + { + // + // The facet being removed may not be implemented by a Python servant + // (e.g., it could be the Process or Properties facet), in which case + // we return None. + // + Ice::ObjectPtr obj = (*self->communicator)->removeAdminFacet(facet); + assert(obj); + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + if(wrapper) + { + return wrapper->getObject(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorSetWrapper(CommunicatorObject* self, PyObject* args) +{ + PyObject* wrapper; + if(!PyArg_ParseTuple(args, STRCAST("O"), &wrapper)) + { + return 0; + } + + assert(!self->wrapper); + self->wrapper = wrapper; + Py_INCREF(self->wrapper); + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetWrapper(CommunicatorObject* self) +{ + assert(self->wrapper); + Py_INCREF(self->wrapper); + return self->wrapper; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetProperties(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::PropertiesPtr properties; + try + { + properties = (*self->communicator)->getProperties(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProperties(properties); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetLogger(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::LoggerPtr logger; + try + { + logger = (*self->communicator)->getLogger(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + // + // The communicator's logger can either be a C++ object (such as + // the default logger supplied by the Ice run time), or a C++ + // wrapper around a Python implementation. If the latter, we + // return it directly. Otherwise, we create a Python object + // that delegates to the C++ object. + // + LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(logger); + if(wrapper) + { + PyObject* obj = wrapper->getObject(); + Py_INCREF(obj); + return obj; + } + + return createLogger(logger); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorAddObjectFactory(CommunicatorObject* self, PyObject* args) +{ + PyObject* factoryType = lookupType("Ice.ObjectFactory"); + assert(factoryType); + + PyObject* factory; + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), factoryType, &factory, &strObj)) + { + return 0; + } + + string id; + if(!getStringArg(strObj, "id", id)) + { + return 0; + } + + ObjectFactoryPtr pof; + try + { + pof = ObjectFactoryPtr::dynamicCast((*self->communicator)->findObjectFactory("")); + assert(pof); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + + } + + if(!pof->add(factory, id)) + { + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorFindObjectFactory(CommunicatorObject* self, PyObject* args) +{ + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj)) + { + return 0; + } + + string id; + if(!getStringArg(strObj, "id", id)) + { + return 0; + } + + ObjectFactoryPtr pof; + try + { + pof = ObjectFactoryPtr::dynamicCast((*self->communicator)->findObjectFactory("")); + assert(pof); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return pof->find(id); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetImplicitContext(CommunicatorObject* self) +{ + Ice::ImplicitContextPtr implicitContext = (*self->communicator)->getImplicitContext(); + + if(implicitContext == 0) + { + Py_INCREF(Py_None); + return Py_None; + } + + return createImplicitContext(implicitContext); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorCreateObjectAdapter(CommunicatorObject* self, PyObject* args) +{ + PyObject* strObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &strObj)) + { + return 0; + } + + string name; + if(!getStringArg(strObj, "name", name)) + { + return 0; + } + + assert(self->communicator); + Ice::ObjectAdapterPtr adapter; + try + { + adapter = (*self->communicator)->createObjectAdapter(name); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* obj = createObjectAdapter(adapter); + if(!obj) + { + try + { + adapter->deactivate(); + } + catch(const Ice::Exception&) + { + } + } + + return obj; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorCreateObjectAdapterWithEndpoints(CommunicatorObject* self, PyObject* args) +{ + PyObject* nameObj; + PyObject* endpointsObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &nameObj, &endpointsObj)) + { + return 0; + } + + string name; + string endpoints; + if(!getStringArg(nameObj, "name", name)) + { + return 0; + } + if(!getStringArg(endpointsObj, "endpoints", endpoints)) + { + return 0; + } + + assert(self->communicator); + Ice::ObjectAdapterPtr adapter; + try + { + adapter = (*self->communicator)->createObjectAdapterWithEndpoints(name, endpoints); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* obj = createObjectAdapter(adapter); + if(!obj) + { + try + { + adapter->deactivate(); + } + catch(const Ice::Exception&) + { + } + } + + return obj; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorCreateObjectAdapterWithRouter(CommunicatorObject* self, PyObject* args) +{ + PyObject* nameObj; + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &nameObj, &p)) + { + return 0; + } + + string name; + if(!getStringArg(nameObj, "name", name)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "createObjectAdapterWithRouter", "rtr", proxy, "Ice.RouterPrx")) + { + return 0; + } + + Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + + assert(self->communicator); + Ice::ObjectAdapterPtr adapter; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock to avoid a potential deadlock. + adapter = (*self->communicator)->createObjectAdapterWithRouter(name, router); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* obj = createObjectAdapter(adapter); + if(!obj) + { + try + { + adapter->deactivate(); + } + catch(const Ice::Exception&) + { + } + } + + return obj; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetDefaultRouter(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::RouterPrx router; + try + { + router = (*self->communicator)->getDefaultRouter(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!router) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* routerProxyType = lookupType("Ice.RouterPrx"); + assert(routerProxyType); + return createProxy(router, *self->communicator, routerProxyType); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorSetDefaultRouter(CommunicatorObject* self, PyObject* args) +{ + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O"), &p)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "setDefaultRouter", "rtr", proxy, "Ice.RouterPrx")) + { + return 0; + } + + Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + + assert(self->communicator); + try + { + (*self->communicator)->setDefaultRouter(router); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorGetDefaultLocator(CommunicatorObject* self) +{ + assert(self->communicator); + Ice::LocatorPrx locator; + try + { + locator = (*self->communicator)->getDefaultLocator(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!locator) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* locatorProxyType = lookupType("Ice.LocatorPrx"); + assert(locatorProxyType); + return createProxy(locator, *self->communicator, locatorProxyType); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +communicatorSetDefaultLocator(CommunicatorObject* self, PyObject* args) +{ + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O"), &p)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "setDefaultLocator", "loc", proxy, "Ice.LocatorPrx")) + { + return 0; + } + + Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + + assert(self->communicator); + try + { + (*self->communicator)->setDefaultLocator(locator); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef CommunicatorMethods[] = +{ + { STRCAST("destroy"), reinterpret_cast<PyCFunction>(communicatorDestroy), METH_NOARGS, + PyDoc_STR(STRCAST("destroy() -> None")) }, + { STRCAST("shutdown"), reinterpret_cast<PyCFunction>(communicatorShutdown), METH_NOARGS, + PyDoc_STR(STRCAST("shutdown() -> None")) }, + { STRCAST("waitForShutdown"), reinterpret_cast<PyCFunction>(communicatorWaitForShutdown), METH_VARARGS, + PyDoc_STR(STRCAST("waitForShutdown() -> None")) }, + { STRCAST("isShutdown"), reinterpret_cast<PyCFunction>(communicatorIsShutdown), METH_NOARGS, + PyDoc_STR(STRCAST("isShutdown() -> bool")) }, + { STRCAST("stringToProxy"), reinterpret_cast<PyCFunction>(communicatorStringToProxy), METH_VARARGS, + PyDoc_STR(STRCAST("stringToProxy(str) -> Ice.ObjectPrx")) }, + { STRCAST("proxyToString"), reinterpret_cast<PyCFunction>(communicatorProxyToString), METH_VARARGS, + PyDoc_STR(STRCAST("proxyToString(Ice.ObjectPrx) -> string")) }, + { STRCAST("propertyToProxy"), reinterpret_cast<PyCFunction>(communicatorPropertyToProxy), METH_VARARGS, + PyDoc_STR(STRCAST("propertyToProxy(str) -> Ice.ObjectPrx")) }, + { STRCAST("proxyToProperty"), reinterpret_cast<PyCFunction>(communicatorProxyToProperty), METH_VARARGS, + PyDoc_STR(STRCAST("proxyToProperty(Ice.ObjectPrx, str) -> dict")) }, + { STRCAST("stringToIdentity"), reinterpret_cast<PyCFunction>(communicatorStringToIdentity), METH_VARARGS, + PyDoc_STR(STRCAST("stringToIdentity(str) -> Ice.Identity")) }, + { STRCAST("identityToString"), reinterpret_cast<PyCFunction>(communicatorIdentityToString), METH_VARARGS, + PyDoc_STR(STRCAST("identityToString(Ice.Identity) -> string")) }, + { STRCAST("createObjectAdapter"), reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapter), METH_VARARGS, + PyDoc_STR(STRCAST("createObjectAdapter(name) -> Ice.ObjectAdapter")) }, + { STRCAST("createObjectAdapterWithEndpoints"), + reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapterWithEndpoints), METH_VARARGS, + PyDoc_STR(STRCAST("createObjectAdapterWithEndpoints(name, endpoints) -> Ice.ObjectAdapter")) }, + { STRCAST("createObjectAdapterWithRouter"), + reinterpret_cast<PyCFunction>(communicatorCreateObjectAdapterWithRouter), METH_VARARGS, + PyDoc_STR(STRCAST("createObjectAdapterWithRouter(name, router) -> Ice.ObjectAdapter")) }, + { STRCAST("addObjectFactory"), reinterpret_cast<PyCFunction>(communicatorAddObjectFactory), METH_VARARGS, + PyDoc_STR(STRCAST("addObjectFactory(factory, id) -> None")) }, + { STRCAST("findObjectFactory"), reinterpret_cast<PyCFunction>(communicatorFindObjectFactory), METH_VARARGS, + PyDoc_STR(STRCAST("findObjectFactory(id) -> Ice.ObjectFactory")) }, + { STRCAST("getImplicitContext"), reinterpret_cast<PyCFunction>(communicatorGetImplicitContext), METH_NOARGS, + PyDoc_STR(STRCAST("getImplicitContext() -> Ice.ImplicitContext")) }, + { STRCAST("getProperties"), reinterpret_cast<PyCFunction>(communicatorGetProperties), METH_NOARGS, + PyDoc_STR(STRCAST("getProperties() -> Ice.Properties")) }, + { STRCAST("getLogger"), reinterpret_cast<PyCFunction>(communicatorGetLogger), METH_NOARGS, + PyDoc_STR(STRCAST("getLogger() -> Ice.Logger")) }, + { STRCAST("getDefaultRouter"), reinterpret_cast<PyCFunction>(communicatorGetDefaultRouter), METH_NOARGS, + PyDoc_STR(STRCAST("getDefaultRouter() -> proxy")) }, + { STRCAST("setDefaultRouter"), reinterpret_cast<PyCFunction>(communicatorSetDefaultRouter), METH_VARARGS, + PyDoc_STR(STRCAST("setDefaultRouter(proxy) -> None")) }, + { STRCAST("getDefaultLocator"), reinterpret_cast<PyCFunction>(communicatorGetDefaultLocator), METH_NOARGS, + PyDoc_STR(STRCAST("getDefaultLocator() -> proxy")) }, + { STRCAST("setDefaultLocator"), reinterpret_cast<PyCFunction>(communicatorSetDefaultLocator), METH_VARARGS, + PyDoc_STR(STRCAST("setDefaultLocator(proxy) -> None")) }, + { STRCAST("flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorFlushBatchRequests), METH_NOARGS, + PyDoc_STR(STRCAST("flushBatchRequests() -> None")) }, + { STRCAST("begin_flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorBeginFlushBatchRequests), + METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) }, + { STRCAST("end_flushBatchRequests"), reinterpret_cast<PyCFunction>(communicatorEndFlushBatchRequests), + METH_VARARGS, PyDoc_STR(STRCAST("end_flushBatchRequests(Ice.AsyncResult) -> None")) }, + { STRCAST("createAdmin"), reinterpret_cast<PyCFunction>(communicatorCreateAdmin), METH_VARARGS, + PyDoc_STR(STRCAST("createAdmin(adminAdapter, adminIdentity) -> Ice.ObjectPrx")) }, + { STRCAST("getAdmin"), reinterpret_cast<PyCFunction>(communicatorGetAdmin), METH_NOARGS, + PyDoc_STR(STRCAST("getAdmin() -> Ice.ObjectPrx")) }, + { STRCAST("addAdminFacet"), reinterpret_cast<PyCFunction>(communicatorAddAdminFacet), METH_VARARGS, + PyDoc_STR(STRCAST("addAdminFacet(servant, facet) -> None")) }, + { STRCAST("findAdminFacet"), reinterpret_cast<PyCFunction>(communicatorFindAdminFacet), METH_VARARGS, + PyDoc_STR(STRCAST("findAdminFacet(facet) -> Ice.Object")) }, + { STRCAST("findAllAdminFacets"), reinterpret_cast<PyCFunction>(communicatorFindAllAdminFacets), METH_NOARGS, + PyDoc_STR(STRCAST("findAllAdminFacets() -> dictionary")) }, + { STRCAST("removeAdminFacet"), reinterpret_cast<PyCFunction>(communicatorRemoveAdminFacet), METH_VARARGS, + PyDoc_STR(STRCAST("removeAdminFacet(facet) -> Ice.Object")) }, + { STRCAST("_setWrapper"), reinterpret_cast<PyCFunction>(communicatorSetWrapper), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("_getWrapper"), reinterpret_cast<PyCFunction>(communicatorGetWrapper), METH_NOARGS, + PyDoc_STR(STRCAST("internal function")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject CommunicatorType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Communicator"), /* tp_name */ + sizeof(CommunicatorObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(communicatorDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + CommunicatorMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + reinterpret_cast<initproc>(communicatorInit), /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(communicatorNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initCommunicator(PyObject* module) +{ + _mainThreadId = PyThread_get_thread_ident(); + + if(PyType_Ready(&CommunicatorType) < 0) + { + return false; + } + PyTypeObject* type = &CommunicatorType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Communicator"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::CommunicatorPtr +IcePy::getCommunicator(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&CommunicatorType))); + CommunicatorObject* cobj = reinterpret_cast<CommunicatorObject*>(obj); + return *cobj->communicator; +} + +PyObject* +IcePy::createCommunicator(const Ice::CommunicatorPtr& communicator) +{ + CommunicatorMap::iterator p = _communicatorMap.find(communicator); + if(p != _communicatorMap.end()) + { + Py_INCREF(p->second); + return p->second; + } + + CommunicatorObject* obj = communicatorNew(&CommunicatorType, 0, 0); + if(obj) + { + obj->communicator = new Ice::CommunicatorPtr(communicator); + } + return (PyObject*)obj; +} + +PyObject* +IcePy::getCommunicatorWrapper(const Ice::CommunicatorPtr& communicator) +{ + CommunicatorMap::iterator p = _communicatorMap.find(communicator); + assert(p != _communicatorMap.end()); + CommunicatorObject* obj = reinterpret_cast<CommunicatorObject*>(p->second); + Py_INCREF(obj->wrapper); + return obj->wrapper; +} diff --git a/python/modules/IcePy/Communicator.h b/python/modules/IcePy/Communicator.h new file mode 100644 index 00000000000..3f2ac0452c3 --- /dev/null +++ b/python/modules/IcePy/Communicator.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_COMMUNICATOR_H +#define ICEPY_COMMUNICATOR_H + +#include <Config.h> +#include <Ice/CommunicatorF.h> + +namespace IcePy +{ + +extern PyTypeObject CommunicatorType; + +bool initCommunicator(PyObject*); + +Ice::CommunicatorPtr getCommunicator(PyObject*); + +PyObject* createCommunicator(const Ice::CommunicatorPtr&); +PyObject* getCommunicatorWrapper(const Ice::CommunicatorPtr&); + +} + +extern "C" PyObject* IcePy_initialize(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithProperties(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithLogger(PyObject*, PyObject*); +extern "C" PyObject* IcePy_initializeWithPropertiesAndLogger(PyObject*, PyObject*); + +#endif diff --git a/python/modules/IcePy/Config.h b/python/modules/IcePy/Config.h new file mode 100644 index 00000000000..b21070b9742 --- /dev/null +++ b/python/modules/IcePy/Config.h @@ -0,0 +1,35 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_CONFIG_H +#define ICEPY_CONFIG_H + +// +// This file includes <Python.h> and should always be included first, +// see http://www.python.org/doc/api/includes.html for the details. +// + +// +// COMPILERFIX: This is required to prevent annoying warnings with aCC. +// The aCC -mt option causes the definition of the _POSIX_C_SOURCE macro +// (with another lower value.) and this is causing a warning because of +// the redefinition. +// +#if defined(__HP_aCC) && defined(_POSIX_C_SOURCE) +# undef _POSIX_C_SOURCE +#endif + +#include <Python.h> + +#ifdef STRCAST +# error "STRCAST already defined!" +#endif +#define STRCAST(s) const_cast<char*>(s) + +#endif diff --git a/python/modules/IcePy/Connection.cpp b/python/modules/IcePy/Connection.cpp new file mode 100644 index 00000000000..c761419993a --- /dev/null +++ b/python/modules/IcePy/Connection.cpp @@ -0,0 +1,861 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Connection.h> +#include <Communicator.h> +#include <ConnectionInfo.h> +#include <Endpoint.h> +#include <ObjectAdapter.h> +#include <Operation.h> +#include <Proxy.h> +#include <Thread.h> +#include <Types.h> +#include <Util.h> +#include <Ice/ConnectionAsync.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +extern PyTypeObject ConnectionType; + +struct ConnectionObject +{ + PyObject_HEAD + Ice::ConnectionPtr* connection; + Ice::CommunicatorPtr* communicator; +}; + +class ConnectionCallbackI : public Ice::ConnectionCallback +{ +public: + + ConnectionCallbackI(PyObject* cb, PyObject* con) : + _cb(cb), _con(con) + { + Py_INCREF(cb); + Py_INCREF(con); + } + + virtual ~ConnectionCallbackI() + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_cb); + Py_DECREF(_con); + } + + virtual void heartbeat(const Ice::ConnectionPtr& con) + { + invoke("heartbeat", con); + } + + virtual void closed(const Ice::ConnectionPtr& con) + { + invoke("closed", con); + } + +private: + + void invoke(const string& methodName, const Ice::ConnectionPtr& con) + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. +#ifndef NDEBUG + ConnectionObject* c = reinterpret_cast<ConnectionObject*>(_con); + assert(con == *(c->connection)); +#endif + if(!PyObject_HasAttrString(_cb, STRCAST(methodName.c_str()))) + { + ostringstream ostr; + ostr << "connection callback object does not define " << methodName << "()"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } + else + { + PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), _con); + PyObjectHandle method = PyObject_GetAttrString(_cb, STRCAST(methodName.c_str())); + assert(method.get()); + PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); + if(PyErr_Occurred()) + { + PyException ex; // Retrieve it before another Python API call clears it. + + // + // A callback that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + ex.raise(); + } + } + } + + PyObject* _cb; + PyObject* _con; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static ConnectionObject* +connectionNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + assert(type && type->tp_alloc); + ConnectionObject* self = reinterpret_cast<ConnectionObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->connection = 0; + self->communicator = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +connectionDealloc(ConnectionObject* self) +{ + delete self->connection; + delete self->communicator; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionCompare(ConnectionObject* c1, PyObject* other, int op) +{ + bool result = false; + + if(PyObject_TypeCheck(other, &ConnectionType)) + { + ConnectionObject* c2 = reinterpret_cast<ConnectionObject*>(other); + + switch(op) + { + case Py_EQ: + result = *c1->connection == *c2->connection; + break; + case Py_NE: + result = *c1->connection != *c2->connection; + break; + case Py_LE: + result = *c1->connection <= *c2->connection; + break; + case Py_GE: + result = *c1->connection >= *c2->connection; + break; + case Py_LT: + result = *c1->connection < *c2->connection; + break; + case Py_GT: + result = *c1->connection > *c2->connection; + break; + } + } + else + { + if(op == Py_EQ) + { + result = false; + } + else if(op == Py_NE) + { + result = true; + } + else + { + PyErr_Format(PyExc_TypeError, "can't compare %s to %s", Py_TYPE(c1)->tp_name, Py_TYPE(other)->tp_name); + return 0; + } + } + + PyObject* r = result ? getTrue() : getFalse(); + Py_INCREF(r); + return r; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionClose(ConnectionObject* self, PyObject* args) +{ + int force; + if(!PyArg_ParseTuple(args, STRCAST("i"), &force)) + { + return 0; + } + + assert(self->connection); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->connection)->close(force > 0); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionCreateProxy(ConnectionObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->connection); + assert(self->communicator); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->connection)->createProxy(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->communicator)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionSetAdapter(ConnectionObject* self, PyObject* args) +{ + PyObject* adapterType = lookupType("Ice.ObjectAdapter"); + PyObject* adapter; + if(!PyArg_ParseTuple(args, STRCAST("O!"), adapterType, &adapter)) + { + return 0; + } + + Ice::ObjectAdapterPtr oa = unwrapObjectAdapter(adapter); + assert(oa); + + assert(self->connection); + assert(self->communicator); + try + { + (*self->connection)->setAdapter(oa); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionGetAdapter(ConnectionObject* self) +{ + Ice::ObjectAdapterPtr adapter; + + assert(self->connection); + assert(self->communicator); + try + { + adapter = (*self->connection)->getAdapter(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return wrapObjectAdapter(adapter); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionFlushBatchRequests(ConnectionObject* self) +{ + assert(self->connection); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + (*self->connection)->flushBatchRequests(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionBeginFlushBatchRequests(ConnectionObject* self, PyObject* args, PyObject* kwds) +{ + assert(self->connection); + + static char* argNames[] = + { + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + 0 + }; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &ex, &sent)) + { + return 0; + } + + if(ex == Py_None) + { + ex = 0; + } + if(sent == Py_None) + { + sent = 0; + } + + if(!ex && sent) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("exception callback must also be provided when sent callback is used")); + return 0; + } + + Ice::Callback_Connection_flushBatchRequestsPtr cb; + if(ex || sent) + { + FlushCallbackPtr d = new FlushCallback(ex, sent, "flushBatchRequests"); + cb = Ice::newCallback_Connection_flushBatchRequests(d, &FlushCallback::exception, &FlushCallback::sent); + } + + Ice::AsyncResultPtr result; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + + if(cb) + { + result = (*self->connection)->begin_flushBatchRequests(cb); + } + else + { + result = (*self->connection)->begin_flushBatchRequests(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle communicator = getCommunicatorWrapper(*self->communicator); + return createAsyncResult(result, 0, reinterpret_cast<PyObject*>(self), communicator.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionEndFlushBatchRequests(ConnectionObject* self, PyObject* args) +{ + assert(self->connection); + + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + Ice::AsyncResultPtr r = getAsyncResult(result); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->connection)->end_flushBatchRequests(r); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionSetCallback(ConnectionObject* self, PyObject* args) +{ + assert(self->connection); + + PyObject* callbackType = lookupType("Ice.ConnectionCallback"); + PyObject* cb; + if(!PyArg_ParseTuple(args, STRCAST("O!"), callbackType, &cb)) + { + return 0; + } + + Ice::ConnectionCallbackPtr wrapper = new ConnectionCallbackI(cb, reinterpret_cast<PyObject*>(self)); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->connection)->setCallback(wrapper); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionSetACM(ConnectionObject* self, PyObject* args) +{ + assert(self->connection); + + IceUtil::Optional<Ice::Int> timeout; + IceUtil::Optional<Ice::ACMClose> close; + IceUtil::Optional<Ice::ACMHeartbeat> heartbeat; + + PyObject* acmCloseType = lookupType("Ice.ACMClose"); + PyObject* acmHeartbeatType = lookupType("Ice.ACMHeartbeat"); + PyObject* t; + PyObject* c; + PyObject* h; + if(!PyArg_ParseTuple(args, STRCAST("OOO"), &t, &c, &h)) + { + return 0; + } + + if(t != Unset) + { + timeout = static_cast<Ice::Int>(PyLong_AsLong(t)); + if(PyErr_Occurred()) + { + return 0; + } + } + + if(c != Unset) + { + if(PyObject_IsInstance(c, acmCloseType) == 0) + { + PyErr_Format(PyExc_TypeError, "value for 'close' argument must be Unset or an enumerator of Ice.ACMClose"); + return 0; + } + PyObjectHandle v = PyObject_GetAttrString(c, STRCAST("_value")); + assert(v.get()); + close = static_cast<Ice::ACMClose>(PyLong_AsLong(v.get())); + } + + if(h != Unset) + { + if(PyObject_IsInstance(h, acmHeartbeatType) == 0) + { + PyErr_Format(PyExc_TypeError, + "value for 'heartbeat' argument must be Unset or an enumerator of Ice.ACMHeartbeat"); + return 0; + } + PyObjectHandle v = PyObject_GetAttrString(h, STRCAST("_value")); + assert(v.get()); + heartbeat = static_cast<Ice::ACMHeartbeat>(PyLong_AsLong(v.get())); + } + + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->connection)->setACM(timeout, close, heartbeat); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionGetACM(ConnectionObject* self) +{ + assert(self->connection); + + PyObject* acmType = lookupType("Ice.ACM"); + PyObject* acmCloseType = lookupType("Ice._t_ACMClose"); + PyObject* acmHeartbeatType = lookupType("Ice._t_ACMHeartbeat"); + Ice::ACM acm; + + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + acm = (*self->connection)->getACM(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle r = StructInfo::instantiate(acmType); + if(!r.get()) + { + return 0; + } + + PyObjectHandle timeout = PyLong_FromLong(acm.timeout); + if(!timeout.get()) + { + assert(PyErr_Occurred()); + return 0; + } + + if(PyObject_SetAttrString(r.get(), STRCAST("timeout"), timeout.get()) < 0) + { + assert(PyErr_Occurred()); + return 0; + } + + EnumInfoPtr acmCloseEnum = EnumInfoPtr::dynamicCast(getType(acmCloseType)); + assert(acmCloseEnum); + PyObjectHandle close = acmCloseEnum->enumeratorForValue(static_cast<Ice::Int>(acm.close)); + if(!close.get()) + { + PyErr_Format(PyExc_ValueError, "unexpected value for 'close' member of Ice.ACM"); + return 0; + } + if(PyObject_SetAttrString(r.get(), STRCAST("close"), close.get()) < 0) + { + assert(PyErr_Occurred()); + return 0; + } + + EnumInfoPtr acmHeartbeatEnum = EnumInfoPtr::dynamicCast(getType(acmHeartbeatType)); + assert(acmHeartbeatEnum); + PyObjectHandle heartbeat = acmHeartbeatEnum->enumeratorForValue(static_cast<Ice::Int>(acm.heartbeat)); + if(!heartbeat.get()) + { + PyErr_Format(PyExc_ValueError, "unexpected value for 'heartbeat' member of Ice.ACM"); + return 0; + } + if(PyObject_SetAttrString(r.get(), STRCAST("heartbeat"), heartbeat.get()) < 0) + { + assert(PyErr_Occurred()); + return 0; + } + + return r.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionType(ConnectionObject* self) +{ + assert(self->connection); + string type; + try + { + type = (*self->connection)->type(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(type); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionTimeout(ConnectionObject* self) +{ + assert(self->connection); + int timeout; + try + { + timeout = (*self->connection)->timeout(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return PyLong_FromLong(timeout); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionToString(ConnectionObject* self) +{ + assert(self->connection); + string str; + try + { + str = (*self->connection)->toString(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(str); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionGetInfo(ConnectionObject* self) +{ + assert(self->connection); + try + { + Ice::ConnectionInfoPtr info = (*self->connection)->getInfo(); + return createConnectionInfo(info); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionGetEndpoint(ConnectionObject* self) +{ + assert(self->connection); + try + { + Ice::EndpointPtr endpoint = (*self->connection)->getEndpoint(); + return createEndpoint(endpoint); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionSetBufferSize(ConnectionObject* self, PyObject* args) +{ + int rcvSize; + int sndSize; + if(!PyArg_ParseTuple(args, STRCAST("ii"), &rcvSize, &sndSize)) + { + return 0; + } + + assert(self->connection); + try + { + (*self->connection)->setBufferSize(rcvSize, sndSize); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef ConnectionMethods[] = +{ + { STRCAST("close"), reinterpret_cast<PyCFunction>(connectionClose), METH_VARARGS, + PyDoc_STR(STRCAST("close(bool) -> None")) }, + { STRCAST("createProxy"), reinterpret_cast<PyCFunction>(connectionCreateProxy), METH_VARARGS, + PyDoc_STR(STRCAST("createProxy(Ice.Identity) -> Ice.ObjectPrx")) }, + { STRCAST("setAdapter"), reinterpret_cast<PyCFunction>(connectionSetAdapter), METH_VARARGS, + PyDoc_STR(STRCAST("setAdapter(Ice.ObjectAdapter) -> None")) }, + { STRCAST("getAdapter"), reinterpret_cast<PyCFunction>(connectionGetAdapter), METH_NOARGS, + PyDoc_STR(STRCAST("getAdapter() -> Ice.ObjectAdapter")) }, + { STRCAST("flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionFlushBatchRequests), METH_NOARGS, + PyDoc_STR(STRCAST("flushBatchRequests() -> None")) }, + { STRCAST("begin_flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionBeginFlushBatchRequests), + METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) }, + { STRCAST("end_flushBatchRequests"), reinterpret_cast<PyCFunction>(connectionEndFlushBatchRequests), METH_VARARGS, + PyDoc_STR(STRCAST("end_flushBatchRequests(Ice.AsyncResult) -> None")) }, + { STRCAST("setCallback"), reinterpret_cast<PyCFunction>(connectionSetCallback), METH_VARARGS, + PyDoc_STR(STRCAST("setCallback(Ice.ConnectionCallback) -> None")) }, + { STRCAST("setACM"), reinterpret_cast<PyCFunction>(connectionSetACM), METH_VARARGS, + PyDoc_STR(STRCAST("setACM(int, Ice.ACMClose, Ice.ACMHeartbeat) -> None")) }, + { STRCAST("getACM"), reinterpret_cast<PyCFunction>(connectionGetACM), METH_NOARGS, + PyDoc_STR(STRCAST("getACM() -> Ice.ACM")) }, + { STRCAST("type"), reinterpret_cast<PyCFunction>(connectionType), METH_NOARGS, + PyDoc_STR(STRCAST("type() -> string")) }, + { STRCAST("timeout"), reinterpret_cast<PyCFunction>(connectionTimeout), METH_NOARGS, + PyDoc_STR(STRCAST("timeout() -> int")) }, + { STRCAST("toString"), reinterpret_cast<PyCFunction>(connectionToString), METH_NOARGS, + PyDoc_STR(STRCAST("toString() -> string")) }, + { STRCAST("getInfo"), reinterpret_cast<PyCFunction>(connectionGetInfo), METH_NOARGS, + PyDoc_STR(STRCAST("getInfo() -> Ice.ConnectionInfo")) }, + { STRCAST("getEndpoint"), reinterpret_cast<PyCFunction>(connectionGetEndpoint), METH_NOARGS, + PyDoc_STR(STRCAST("getEndpoint() -> Ice.Endpoint")) }, + { STRCAST("setBufferSize"), reinterpret_cast<PyCFunction>(connectionSetBufferSize), METH_VARARGS, + PyDoc_STR(STRCAST("setBufferSize(int, int) -> None")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ConnectionType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Connection"), /* tp_name */ + sizeof(ConnectionObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(connectionDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +#if PY_VERSION_HEX >= 0x03000000 + Py_TPFLAGS_DEFAULT, /* tp_flags */ +#else + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */ +#endif + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + reinterpret_cast<richcmpfunc>(connectionCompare), /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ConnectionMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(connectionNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initConnection(PyObject* module) +{ + if(PyType_Ready(&ConnectionType) < 0) + { + return false; + } + PyTypeObject* type = &ConnectionType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Connection"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createConnection(const Ice::ConnectionPtr& connection, const Ice::CommunicatorPtr& communicator) +{ + ConnectionObject* obj = connectionNew(&ConnectionType, 0, 0); + if(obj) + { + obj->connection = new Ice::ConnectionPtr(connection); + obj->communicator = new Ice::CommunicatorPtr(communicator); + } + return reinterpret_cast<PyObject*>(obj); +} diff --git a/python/modules/IcePy/Connection.h b/python/modules/IcePy/Connection.h new file mode 100644 index 00000000000..768b98e634e --- /dev/null +++ b/python/modules/IcePy/Connection.h @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_CONNECTION_H +#define ICEPY_CONNECTION_H + +#include <Config.h> +#include <Ice/ConnectionF.h> +#include <Ice/CommunicatorF.h> + +namespace IcePy +{ + +bool initConnection(PyObject*); + +PyObject* createConnection(const Ice::ConnectionPtr&, const Ice::CommunicatorPtr&); + +} + +#endif diff --git a/python/modules/IcePy/ConnectionInfo.cpp b/python/modules/IcePy/ConnectionInfo.cpp new file mode 100644 index 00000000000..2381bb303ba --- /dev/null +++ b/python/modules/IcePy/ConnectionInfo.cpp @@ -0,0 +1,565 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <ConnectionInfo.h> +#include <EndpointInfo.h> +#include <Util.h> +#include <Ice/Object.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct ConnectionInfoObject +{ + PyObject_HEAD + Ice::ConnectionInfoPtr* connectionInfo; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static ConnectionInfoObject* +connectionInfoNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("A connection info cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +connectionInfoDealloc(ConnectionInfoObject* self) +{ + delete self->connectionInfo; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionInfoGetIncoming(ConnectionInfoObject* self) +{ + PyObject* result = (*self->connectionInfo)->incoming ? getTrue() : getFalse(); + Py_INCREF(result); + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionInfoGetAdapterName(ConnectionInfoObject* self) +{ + return createString((*self->connectionInfo)->adapterName); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionInfoGetRcvSize(ConnectionInfoObject* self) +{ + return PyLong_FromLong((*self->connectionInfo)->rcvSize); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +connectionInfoGetSndSize(ConnectionInfoObject* self) +{ + return PyLong_FromLong((*self->connectionInfo)->sndSize); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipConnectionInfoGetLocalAddress(ConnectionInfoObject* self) +{ + Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return createString(info->localAddress); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipConnectionInfoGetLocalPort(ConnectionInfoObject* self) +{ + Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return PyLong_FromLong(info->localPort); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipConnectionInfoGetRemoteAddress(ConnectionInfoObject* self) +{ + Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return createString(info->remoteAddress); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipConnectionInfoGetRemotePort(ConnectionInfoObject* self) +{ + Ice::IPConnectionInfoPtr info = Ice::IPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return PyLong_FromLong(info->remotePort); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +udpConnectionInfoGetMcastAddress(ConnectionInfoObject* self) +{ + Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return createString(info->mcastAddress); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +udpConnectionInfoGetMcastPort(ConnectionInfoObject* self, void* member) +{ + Ice::UDPConnectionInfoPtr info = Ice::UDPConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + return PyLong_FromLong(info->mcastPort); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +wsConnectionInfoGetHeaders(ConnectionInfoObject* self) +{ + Ice::WSConnectionInfoPtr info = Ice::WSConnectionInfoPtr::dynamicCast(*self->connectionInfo); + assert(info); + + PyObjectHandle result = PyDict_New(); + if(result.get()) + { + for(Ice::HeaderDict::iterator p = info->headers.begin(); p != info->headers.end(); ++p) + { + PyObjectHandle key = createString(p->first); + PyObjectHandle val = createString(p->second); + if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) + { + return 0; + } + } + } + + return result.release(); +} + +static PyGetSetDef ConnectionInfoGetters[] = +{ + { STRCAST("incoming"), reinterpret_cast<getter>(connectionInfoGetIncoming), 0, + PyDoc_STR(STRCAST("whether connection is incoming")), 0 }, + { STRCAST("adapterName"), reinterpret_cast<getter>(connectionInfoGetAdapterName), 0, + PyDoc_STR(STRCAST("adapter associated the connection")), 0 }, + { STRCAST("rcvSize"), reinterpret_cast<getter>(connectionInfoGetRcvSize), 0, + PyDoc_STR(STRCAST("receive buffer size")), 0 }, + { STRCAST("sndSize"), reinterpret_cast<getter>(connectionInfoGetSndSize), 0, + PyDoc_STR(STRCAST("send buffer size")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef IPConnectionInfoGetters[] = +{ + { STRCAST("localAddress"), reinterpret_cast<getter>(ipConnectionInfoGetLocalAddress), 0, + PyDoc_STR(STRCAST("local address")), 0 }, + { STRCAST("localPort"), reinterpret_cast<getter>(ipConnectionInfoGetLocalPort), 0, + PyDoc_STR(STRCAST("local port")), 0 }, + { STRCAST("remoteAddress"), reinterpret_cast<getter>(ipConnectionInfoGetRemoteAddress), 0, + PyDoc_STR(STRCAST("remote address")), 0 }, + { STRCAST("remotePort"), reinterpret_cast<getter>(ipConnectionInfoGetRemotePort), 0, + PyDoc_STR(STRCAST("remote port")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef UDPConnectionInfoGetters[] = +{ + { STRCAST("mcastAddress"), reinterpret_cast<getter>(udpConnectionInfoGetMcastAddress), 0, + PyDoc_STR(STRCAST("multicast address")), 0 }, + { STRCAST("mcastPort"), reinterpret_cast<getter>(udpConnectionInfoGetMcastPort), 0, + PyDoc_STR(STRCAST("multicast port")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef WSConnectionInfoGetters[] = +{ + { STRCAST("headers"), reinterpret_cast<getter>(wsConnectionInfoGetHeaders), 0, + PyDoc_STR(STRCAST("request headers")), 0 }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.ConnectionInfo"), /* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + ConnectionInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject IPConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.IPConnectionInfo"), /* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + IPConnectionInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject TCPConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.TCPConnectionInfo"),/* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject UDPConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.UDPConnectionInfo"),/* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + UDPConnectionInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject WSConnectionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.WSConnectionInfo"),/* tp_name */ + sizeof(ConnectionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + (destructor)connectionInfoDealloc, /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + WSConnectionInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + (newfunc)connectionInfoNew, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initConnectionInfo(PyObject* module) +{ + if(PyType_Ready(&ConnectionInfoType) < 0) + { + return false; + } + PyTypeObject* type = &ConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + IPConnectionInfoType.tp_base = &ConnectionInfoType; // Force inheritance from ConnectionInfoType. + if(PyType_Ready(&IPConnectionInfoType) < 0) + { + return false; + } + type = &IPConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("IPConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + TCPConnectionInfoType.tp_base = &IPConnectionInfoType; // Force inheritance from IPConnectionInfoType. + if(PyType_Ready(&TCPConnectionInfoType) < 0) + { + return false; + } + type = &TCPConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("TCPConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + UDPConnectionInfoType.tp_base = &IPConnectionInfoType; // Force inheritance from IPConnectionType. + if(PyType_Ready(&UDPConnectionInfoType) < 0) + { + return false; + } + type = &UDPConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("UDPConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + WSConnectionInfoType.tp_base = &IPConnectionInfoType; // Force inheritance from IPConnectionType. + if(PyType_Ready(&WSConnectionInfoType) < 0) + { + return false; + } + type = &WSConnectionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("WSConnectionInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::ConnectionInfoPtr +IcePy::getConnectionInfo(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&ConnectionInfoType))); + ConnectionInfoObject* eobj = reinterpret_cast<ConnectionInfoObject*>(obj); + return *eobj->connectionInfo; +} + +PyObject* +IcePy::createConnectionInfo(const Ice::ConnectionInfoPtr& connectionInfo) +{ + PyTypeObject* type; + if(Ice::TCPConnectionInfoPtr::dynamicCast(connectionInfo)) + { + type = &TCPConnectionInfoType; + } + else if(Ice::UDPConnectionInfoPtr::dynamicCast(connectionInfo)) + { + type = &UDPConnectionInfoType; + } + else if(Ice::WSConnectionInfoPtr::dynamicCast(connectionInfo)) + { + type = &WSConnectionInfoType; + } + else if(Ice::IPConnectionInfoPtr::dynamicCast(connectionInfo)) + { + type = &IPConnectionInfoType; + } + else + { + type = &ConnectionInfoType; + } + + ConnectionInfoObject* obj = reinterpret_cast<ConnectionInfoObject*>(type->tp_alloc(type, 0)); + if(!obj) + { + return 0; + } + obj->connectionInfo = new Ice::ConnectionInfoPtr(connectionInfo); + + return (PyObject*)obj; +} diff --git a/python/modules/IcePy/ConnectionInfo.h b/python/modules/IcePy/ConnectionInfo.h new file mode 100644 index 00000000000..d3391653c81 --- /dev/null +++ b/python/modules/IcePy/ConnectionInfo.h @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_CONNECTION_INFO_H +#define ICEPY_CONNECTION_INFO_H + +#include <Config.h> +#include <Ice/Connection.h> + +namespace IcePy +{ + +extern PyTypeObject ConnectionInfoType; + +bool initConnectionInfo(PyObject*); + +PyObject* createConnectionInfo(const Ice::ConnectionInfoPtr&); +Ice::ConnectionInfoPtr getConnectionInfo(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/Current.cpp b/python/modules/IcePy/Current.cpp new file mode 100644 index 00000000000..897630bb811 --- /dev/null +++ b/python/modules/IcePy/Current.cpp @@ -0,0 +1,349 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Current.h> +#include <structmember.h> +#include <Connection.h> +#include <ObjectAdapter.h> +#include <Util.h> +#include <Ice/ObjectAdapter.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct CurrentObject +{ + PyObject_HEAD + Ice::Current* current; + PyObject* adapter; + PyObject* con; + PyObject* id; + PyObject* facet; + PyObject* operation; + PyObject* mode; + PyObject* ctx; + PyObject* requestId; + PyObject* encoding; +}; + +// +// Member identifiers. +// +const Py_ssize_t CURRENT_ADAPTER = 0; +const Py_ssize_t CURRENT_CONNECTION = 1; +const Py_ssize_t CURRENT_ID = 2; +const Py_ssize_t CURRENT_FACET = 3; +const Py_ssize_t CURRENT_OPERATION = 4; +const Py_ssize_t CURRENT_MODE = 5; +const Py_ssize_t CURRENT_CTX = 6; +const Py_ssize_t CURRENT_REQUEST_ID = 7; +const Py_ssize_t CURRENT_ENCODING = 8; + +} + +#ifdef WIN32 +extern "C" +#endif +static CurrentObject* +currentNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + CurrentObject* self = reinterpret_cast<CurrentObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + + self->current = new Ice::Current; + self->adapter = 0; + self->con = 0; + self->id = 0; + self->facet = 0; + self->operation = 0; + self->mode = 0; + self->ctx = 0; + self->requestId = 0; + self->encoding = 0; + + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +currentDealloc(CurrentObject* self) +{ + Py_XDECREF(self->adapter); + Py_XDECREF(self->con); + Py_XDECREF(self->id); + Py_XDECREF(self->facet); + Py_XDECREF(self->operation); + Py_XDECREF(self->mode); + Py_XDECREF(self->ctx); + Py_XDECREF(self->requestId); + Py_XDECREF(self->encoding); + delete self->current; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +currentGetter(CurrentObject* self, void* closure) +{ + // + // This function intercepts requests for attributes of a Current object. We use this + // lazy initialization in order to minimize the cost of translating Ice::Current into a + // Python object for every upcall. + // + PyObject* result = 0; + + assert(self->current); + + long field = reinterpret_cast<long>(closure); + switch(field) + { + case CURRENT_ADAPTER: + { + if(!self->adapter) + { + self->adapter = wrapObjectAdapter(self->current->adapter); + if(!self->adapter) + { + return 0; + } + } + Py_INCREF(self->adapter); + result = self->adapter; + break; + } + case CURRENT_CONNECTION: + { + if(!self->con) + { + self->con = createConnection(self->current->con, self->current->adapter->getCommunicator()); + if(!self->con) + { + return 0; + } + } + Py_INCREF(self->con); + result = self->con; + break; + } + case CURRENT_ID: + { + if(!self->id) + { + self->id = createIdentity(self->current->id); + } + Py_INCREF(self->id); + result = self->id; + break; + } + case CURRENT_FACET: + { + if(!self->facet) + { + self->facet = createString(self->current->facet); + } + Py_INCREF(self->facet); + result = self->facet; + break; + } + case CURRENT_OPERATION: + { + if(!self->operation) + { + self->operation = createString(self->current->operation); + } + Py_INCREF(self->operation); + result = self->operation; + break; + } + case CURRENT_MODE: + { + if(!self->mode) + { + PyObject* type = lookupType("Ice.OperationMode"); + assert(type); + const char* enumerator = 0; + switch(self->current->mode) + { + case Ice::Normal: + enumerator = "Normal"; + break; + case Ice::Nonmutating: + enumerator = "Nonmutating"; + break; + case Ice::Idempotent: + enumerator = "Idempotent"; + break; + } + self->mode = PyObject_GetAttrString(type, STRCAST(enumerator)); + assert(self->mode); + } + Py_INCREF(self->mode); + result = self->mode; + break; + } + case CURRENT_CTX: + { + if(!self->ctx) + { + self->ctx = PyDict_New(); + if(self->ctx && !contextToDictionary(self->current->ctx, self->ctx)) + { + Py_DECREF(self->ctx); + self->ctx = 0; + break; + } + } + Py_INCREF(self->ctx); + result = self->ctx; + break; + } + case CURRENT_REQUEST_ID: + { + if(!self->requestId) + { + self->requestId = PyLong_FromLong(self->current->requestId); + assert(self->requestId); + } + Py_INCREF(self->requestId); + result = self->requestId; + break; + } + case CURRENT_ENCODING: + { + if(!self->encoding) + { + self->encoding = IcePy::createEncodingVersion(self->current->encoding); + assert(self->encoding); + } + Py_INCREF(self->encoding); + result = self->encoding; + break; + } + } + + return result; +} + +static PyGetSetDef CurrentGetSetters[] = +{ + { STRCAST("adapter"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("object adapter"), + reinterpret_cast<void*>(CURRENT_ADAPTER) }, + { STRCAST("con"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("connection info"), + reinterpret_cast<void*>(CURRENT_CONNECTION) }, + { STRCAST("id"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("identity"), + reinterpret_cast<void*>(CURRENT_ID) }, + { STRCAST("facet"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("facet name"), + reinterpret_cast<void*>(CURRENT_FACET) }, + { STRCAST("operation"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("operation name"), + reinterpret_cast<void*>(CURRENT_OPERATION) }, + { STRCAST("mode"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("operation mode"), + reinterpret_cast<void*>(CURRENT_MODE) }, + { STRCAST("ctx"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("context"), + reinterpret_cast<void*>(CURRENT_CTX) }, + { STRCAST("requestId"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("requestId"), + reinterpret_cast<void*>(CURRENT_REQUEST_ID) }, + { STRCAST("encoding"), reinterpret_cast<getter>(currentGetter), 0, STRCAST("encoding"), + reinterpret_cast<void*>(CURRENT_ENCODING) }, + { 0 } /* Sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject CurrentType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Current"), /* tp_name */ + sizeof(CurrentObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(currentDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + CurrentGetSetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(currentNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initCurrent(PyObject* module) +{ + if(PyType_Ready(&CurrentType) < 0) + { + return false; + } + PyTypeObject* type = &CurrentType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Current"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createCurrent(const Ice::Current& current) +{ + // + // Return an instance of IcePy.Current to hold the current information. + // + CurrentObject* obj = currentNew(&CurrentType, 0, 0); + if(obj) + { + *obj->current = current; + } + return reinterpret_cast<PyObject*>(obj); +} diff --git a/python/modules/IcePy/Current.h b/python/modules/IcePy/Current.h new file mode 100644 index 00000000000..c0f52654c30 --- /dev/null +++ b/python/modules/IcePy/Current.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_CURRENT_H +#define ICEPY_CURRENT_H + +#include <Config.h> +#include <Ice/Current.h> + +namespace IcePy +{ + +extern PyTypeObject CurrentType; + +bool initCurrent(PyObject*); + +PyObject* createCurrent(const Ice::Current&); + +} + +#endif diff --git a/python/modules/IcePy/Endpoint.cpp b/python/modules/IcePy/Endpoint.cpp new file mode 100644 index 00000000000..0ee59b6c757 --- /dev/null +++ b/python/modules/IcePy/Endpoint.cpp @@ -0,0 +1,256 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Endpoint.h> +#include <EndpointInfo.h> +#include <Util.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct EndpointObject +{ + PyObject_HEAD + Ice::EndpointPtr* endpoint; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static EndpointObject* +endpointNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("An endpoint cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +endpointDealloc(EndpointObject* self) +{ + delete self->endpoint; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointCompare(EndpointObject* p1, PyObject* other, int op) +{ + bool result = false; + + if(PyObject_TypeCheck(other, &EndpointType)) + { + EndpointObject* p2 = reinterpret_cast<EndpointObject*>(other); + + switch(op) + { + case Py_EQ: + result = *p1->endpoint == *p2->endpoint; + break; + case Py_NE: + result = *p1->endpoint != *p2->endpoint; + break; + case Py_LE: + result = *p1->endpoint <= *p2->endpoint; + break; + case Py_GE: + result = *p1->endpoint >= *p2->endpoint; + break; + case Py_LT: + result = *p1->endpoint < *p2->endpoint; + break; + case Py_GT: + result = *p1->endpoint > *p2->endpoint; + break; + } + } + else + { + if(op == Py_EQ) + { + result = false; + } + else if(op == Py_NE) + { + result = true; + } + else + { + PyErr_Format(PyExc_TypeError, "can't compare %s to %s", Py_TYPE(p1)->tp_name, Py_TYPE(other)->tp_name); + return 0; + } + } + + PyObject* r = result ? getTrue() : getFalse(); + Py_INCREF(r); + return r; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointToString(EndpointObject* self) +{ + assert(self->endpoint); + try + { + string str = (*self->endpoint)->toString(); + return createString(str); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointRepr(EndpointObject* self) +{ + return endpointToString(self); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointGetInfo(EndpointObject* self) +{ + assert(self->endpoint); + try + { + Ice::EndpointInfoPtr info = (*self->endpoint)->getInfo(); + return createEndpointInfo(info); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +static PyMethodDef EndpointMethods[] = +{ + { STRCAST("toString"), reinterpret_cast<PyCFunction>(endpointToString), METH_NOARGS, + PyDoc_STR(STRCAST("toString() -> string")) }, + { STRCAST("getInfo"), reinterpret_cast<PyCFunction>(endpointGetInfo), METH_NOARGS, + PyDoc_STR(STRCAST("getInfo() -> Ice.EndpointInfo")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject EndpointType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Endpoint"), /* tp_name */ + sizeof(EndpointObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + reinterpret_cast<reprfunc>(endpointRepr), /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +#if PY_VERSION_HEX >= 0x03000000 + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE, /* tp_flags */ +#else + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */ +#endif + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + reinterpret_cast<richcmpfunc>(endpointCompare), /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + EndpointMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +}; + +bool +IcePy::initEndpoint(PyObject* module) +{ + if(PyType_Ready(&EndpointType) < 0) + { + return false; + } + PyTypeObject* type = &EndpointType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Endpoint"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::EndpointPtr +IcePy::getEndpoint(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&EndpointType))); + EndpointObject* eobj = reinterpret_cast<EndpointObject*>(obj); + return *eobj->endpoint; +} + +PyObject* +IcePy::createEndpoint(const Ice::EndpointPtr& endpoint) +{ + EndpointObject* obj = reinterpret_cast<EndpointObject*>(EndpointType.tp_alloc(&EndpointType, 0)); + if(!obj) + { + return 0; + } + obj->endpoint = new Ice::EndpointPtr(endpoint); + return (PyObject*)obj; +} diff --git a/python/modules/IcePy/Endpoint.h b/python/modules/IcePy/Endpoint.h new file mode 100644 index 00000000000..c3a9224391b --- /dev/null +++ b/python/modules/IcePy/Endpoint.h @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_ENDPOINT_H +#define ICEPY_ENDPOINT_H + +#include <Config.h> +#include <Ice/Endpoint.h> + +namespace IcePy +{ + +extern PyTypeObject EndpointType; + +bool initEndpoint(PyObject*); + +PyObject* createEndpoint(const Ice::EndpointPtr&); +Ice::EndpointPtr getEndpoint(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/EndpointInfo.cpp b/python/modules/IcePy/EndpointInfo.cpp new file mode 100644 index 00000000000..a712cb81186 --- /dev/null +++ b/python/modules/IcePy/EndpointInfo.cpp @@ -0,0 +1,695 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <EndpointInfo.h> +#include <Util.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct EndpointInfoObject +{ + PyObject_HEAD + Ice::EndpointInfoPtr* endpointInfo; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static EndpointInfoObject* +endpointInfoNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("An endpoint info cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +endpointInfoDealloc(EndpointInfoObject* self) +{ + delete self->endpointInfo; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +// +// Ice::EndpointInfo::type +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoType(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + try + { + Ice::Short type = (*self->endpointInfo)->type(); + return PyLong_FromLong(type); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +// +// Ice::EndpointInfo::datagram +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoDatagram(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + PyObject* b; + try + { + b = (*self->endpointInfo)->datagram() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +// +// Ice::EndpointInfo::secure +// +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoSecure(EndpointInfoObject* self) +{ + assert(self->endpointInfo); + PyObject* b; + try + { + b = (*self->endpointInfo)->secure() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoGetTimeout(EndpointInfoObject* self) +{ + return PyLong_FromLong((*self->endpointInfo)->timeout); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +endpointInfoGetCompress(EndpointInfoObject* self) +{ + PyObject* result = (*self->endpointInfo)->compress ? getTrue() : getFalse(); + Py_INCREF(result); + return result; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipEndpointInfoGetHost(EndpointInfoObject* self) +{ + Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return createString(info->host); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipEndpointInfoGetSourceAddress(EndpointInfoObject* self) +{ + Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return createString(info->sourceAddress); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +ipEndpointInfoGetPort(EndpointInfoObject* self) +{ + Ice::IPEndpointInfoPtr info = Ice::IPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return PyLong_FromLong(info->port); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +udpEndpointInfoGetMcastInterface(EndpointInfoObject* self) +{ + Ice::UDPEndpointInfoPtr info = Ice::UDPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return createString(info->mcastInterface); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +udpEndpointInfoGetMcastTtl(EndpointInfoObject* self) +{ + Ice::UDPEndpointInfoPtr info = Ice::UDPEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return PyLong_FromLong(info->mcastTtl); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +wsEndpointInfoGetResource(EndpointInfoObject* self) +{ + Ice::WSEndpointInfoPtr info = Ice::WSEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return createString(info->resource); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +opaqueEndpointInfoGetRawBytes(EndpointInfoObject* self) +{ + Ice::OpaqueEndpointInfoPtr info = Ice::OpaqueEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); +#if PY_VERSION_HEX >= 0x03000000 + return PyBytes_FromStringAndSize(reinterpret_cast<const char*>(&info->rawBytes[0]), + static_cast<int>(info->rawBytes.size())); +#else + return PyString_FromStringAndSize(reinterpret_cast<const char*>(&info->rawBytes[0]), + static_cast<int>(info->rawBytes.size())); +#endif +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +opaqueEndpointInfoGetRawEncoding(EndpointInfoObject* self) +{ + Ice::OpaqueEndpointInfoPtr info = Ice::OpaqueEndpointInfoPtr::dynamicCast(*self->endpointInfo); + assert(info); + return IcePy::createEncodingVersion(info->rawEncoding); +} + +static PyMethodDef EndpointInfoMethods[] = +{ + { STRCAST("type"), reinterpret_cast<PyCFunction>(endpointInfoType), METH_NOARGS, + PyDoc_STR(STRCAST("type() -> int")) }, + { STRCAST("datagram"), reinterpret_cast<PyCFunction>(endpointInfoDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("datagram() -> bool")) }, + { STRCAST("secure"), reinterpret_cast<PyCFunction>(endpointInfoSecure), METH_NOARGS, + PyDoc_STR(STRCAST("secure() -> bool")) }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef EndpointInfoGetters[] = +{ + { STRCAST("timeout"), reinterpret_cast<getter>(endpointInfoGetTimeout), 0, + PyDoc_STR(STRCAST("timeout in milliseconds")), 0 }, + { STRCAST("compress"), reinterpret_cast<getter>(endpointInfoGetCompress), 0, + PyDoc_STR(STRCAST("compression status")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef IPEndpointInfoGetters[] = +{ + { STRCAST("host"), reinterpret_cast<getter>(ipEndpointInfoGetHost), 0, + PyDoc_STR(STRCAST("host name or IP address")), 0 }, + { STRCAST("port"), reinterpret_cast<getter>(ipEndpointInfoGetPort), 0, + PyDoc_STR(STRCAST("TCP port number")), 0 }, + { STRCAST("sourceAddress"), reinterpret_cast<getter>(ipEndpointInfoGetSourceAddress), 0, + PyDoc_STR(STRCAST("source IP address")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef UDPEndpointInfoGetters[] = +{ + { STRCAST("mcastInterface"), reinterpret_cast<getter>(udpEndpointInfoGetMcastInterface), 0, + PyDoc_STR(STRCAST("multicast interface")), 0 }, + { STRCAST("mcastTtl"), reinterpret_cast<getter>(udpEndpointInfoGetMcastTtl), 0, + PyDoc_STR(STRCAST("multicast time-to-live")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef WSEndpointInfoGetters[] = +{ + { STRCAST("resource"), reinterpret_cast<getter>(wsEndpointInfoGetResource), 0, + PyDoc_STR(STRCAST("resource")), 0 }, + { 0, 0 } /* sentinel */ +}; + +static PyGetSetDef OpaqueEndpointInfoGetters[] = +{ + { STRCAST("rawBytes"), reinterpret_cast<getter>(opaqueEndpointInfoGetRawBytes), 0, + PyDoc_STR(STRCAST("raw encoding")), 0 }, + { STRCAST("rawEncoding"), reinterpret_cast<getter>(opaqueEndpointInfoGetRawEncoding), 0, + PyDoc_STR(STRCAST("raw encoding version")), 0 }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject EndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.EndpointInfo"), /* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + EndpointInfoMethods, /* tp_methods */ + 0, /* tp_members */ + EndpointInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject IPEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.IPEndpointInfo"), /* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + IPEndpointInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject TCPEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.TCPEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject UDPEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.UDPEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + UDPEndpointInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject WSEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.WSEndpointInfo"), /* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + WSEndpointInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject OpaqueEndpointInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.OpaqueEndpointInfo"),/* tp_name */ + sizeof(EndpointInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(endpointInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + OpaqueEndpointInfoGetters, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(endpointInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initEndpointInfo(PyObject* module) +{ + if(PyType_Ready(&EndpointInfoType) < 0) + { + return false; + } + PyTypeObject* type = &EndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("EndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + IPEndpointInfoType.tp_base = &EndpointInfoType; // Force inheritance from EndpointInfoType. + if(PyType_Ready(&IPEndpointInfoType) < 0) + { + return false; + } + type = &IPEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("IPEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + TCPEndpointInfoType.tp_base = &IPEndpointInfoType; // Force inheritance from IPEndpointInfoType. + if(PyType_Ready(&TCPEndpointInfoType) < 0) + { + return false; + } + type = &TCPEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("TCPEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + UDPEndpointInfoType.tp_base = &IPEndpointInfoType; // Force inheritance from IPEndpointType. + if(PyType_Ready(&UDPEndpointInfoType) < 0) + { + return false; + } + type = &UDPEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("UDPEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + WSEndpointInfoType.tp_base = &IPEndpointInfoType; // Force inheritance from IPEndpointType. + if(PyType_Ready(&WSEndpointInfoType) < 0) + { + return false; + } + type = &WSEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("WSEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + OpaqueEndpointInfoType.tp_base = &EndpointInfoType; // Force inheritance from EndpointType. + if(PyType_Ready(&OpaqueEndpointInfoType) < 0) + { + return false; + } + type = &OpaqueEndpointInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("OpaqueEndpointInfo"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +Ice::EndpointInfoPtr +IcePy::getEndpointInfo(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&EndpointInfoType))); + EndpointInfoObject* eobj = reinterpret_cast<EndpointInfoObject*>(obj); + return *eobj->endpointInfo; +} + +PyObject* +IcePy::createEndpointInfo(const Ice::EndpointInfoPtr& endpointInfo) +{ + PyTypeObject* type; + if(Ice::TCPEndpointInfoPtr::dynamicCast(endpointInfo)) + { + type = &TCPEndpointInfoType; + } + else if(Ice::UDPEndpointInfoPtr::dynamicCast(endpointInfo)) + { + type = &UDPEndpointInfoType; + } + else if(Ice::WSEndpointInfoPtr::dynamicCast(endpointInfo)) + { + type = &WSEndpointInfoType; + } + else if(Ice::OpaqueEndpointInfoPtr::dynamicCast(endpointInfo)) + { + type = &OpaqueEndpointInfoType; + } + else if(Ice::IPEndpointInfoPtr::dynamicCast(endpointInfo)) + { + type = &IPEndpointInfoType; + } + else + { + type = &EndpointInfoType; + } + + EndpointInfoObject* obj = reinterpret_cast<EndpointInfoObject*>(type->tp_alloc(type, 0)); + if(!obj) + { + return 0; + } + obj->endpointInfo = new Ice::EndpointInfoPtr(endpointInfo); + + return (PyObject*)obj; +} diff --git a/python/modules/IcePy/EndpointInfo.h b/python/modules/IcePy/EndpointInfo.h new file mode 100644 index 00000000000..d4a773d432a --- /dev/null +++ b/python/modules/IcePy/EndpointInfo.h @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_ENDPOINT_INFO_H +#define ICEPY_ENDPOINT_INFO_H + +#include <Config.h> +#include <Ice/Endpoint.h> + +namespace IcePy +{ + +extern PyTypeObject EndpointInfoType; + +bool initEndpointInfo(PyObject*); + +PyObject* createEndpointInfo(const Ice::EndpointInfoPtr&); +Ice::EndpointInfoPtr getEndpointInfo(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/IcePy.rc b/python/modules/IcePy/IcePy.rc new file mode 100644 index 00000000000..93803e9e407 --- /dev/null +++ b/python/modules/IcePy/IcePy.rc @@ -0,0 +1,38 @@ +#include "winver.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,6,0,0 + PRODUCTVERSION 3,6,0,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG + #define INTERNALNAME "IcePy_d\0" + #define ORIGINALFILENAME "IcePy_d.pyd\0" +#else + FILEFLAGS 0x0L + #define INTERNALNAME "IcePy\0" + #define ORIGINALFILENAME "IcePy.pyd\0" +#endif + FILEOS 0x4L + FILETYPE VFT_DLL + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "ZeroC, Inc.\0" + VALUE "FileDescription", "Ice for Python Extension\0" + VALUE "FileVersion", "3.6.0\0" + VALUE "InternalName", INTERNALNAME + VALUE "LegalCopyright", "Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.\0" + VALUE "OriginalFilename", ORIGINALFILENAME + VALUE "ProductName", "Ice\0" + VALUE "ProductVersion", "3.6.0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/python/modules/IcePy/ImplicitContext.cpp b/python/modules/IcePy/ImplicitContext.cpp new file mode 100644 index 00000000000..b1a183b0d47 --- /dev/null +++ b/python/modules/IcePy/ImplicitContext.cpp @@ -0,0 +1,392 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <ImplicitContext.h> +#include <ObjectAdapter.h> +#include <Proxy.h> +#include <Util.h> +#include <Ice/ImplicitContext.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +extern PyTypeObject ImplicitContextType; + +struct ImplicitContextObject +{ + PyObject_HEAD + Ice::ImplicitContextPtr* implicitContext; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static ImplicitContextObject* +implicitContextNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + ImplicitContextObject* self = reinterpret_cast<ImplicitContextObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->implicitContext = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +implicitContextDealloc(ImplicitContextObject* self) +{ + delete self->implicitContext; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextCompare(ImplicitContextObject* c1, PyObject* other, int op) +{ + bool result = false; + + if(PyObject_TypeCheck(other, &ImplicitContextType)) + { + ImplicitContextObject* c2 = reinterpret_cast<ImplicitContextObject*>(other); + + switch(op) + { + case Py_EQ: + result = *c1->implicitContext == *c2->implicitContext; + break; + case Py_NE: + result = *c1->implicitContext != *c2->implicitContext; + break; + case Py_LE: + result = *c1->implicitContext <= *c2->implicitContext; + break; + case Py_GE: + result = *c1->implicitContext >= *c2->implicitContext; + break; + case Py_LT: + result = *c1->implicitContext < *c2->implicitContext; + break; + case Py_GT: + result = *c1->implicitContext > *c2->implicitContext; + break; + } + } + else + { + if(op == Py_EQ) + { + result = false; + } + else if(op == Py_NE) + { + result = true; + } + else + { + PyErr_Format(PyExc_TypeError, "can't compare %s to %s", Py_TYPE(c1)->tp_name, Py_TYPE(other)->tp_name); + return 0; + } + } + + PyObject* r = result ? getTrue() : getFalse(); + Py_INCREF(r); + return r; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextGetContext(ImplicitContextObject* self) +{ + Ice::Context ctx = (*self->implicitContext)->getContext(); + + PyObjectHandle dict = PyDict_New(); + if(!dict.get()) + { + return 0; + } + + if(!contextToDictionary(ctx, dict.get())) + { + return 0; + } + + return dict.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextSetContext(ImplicitContextObject* self, PyObject* args) +{ + PyObject* dict; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &PyDict_Type, &dict)) + { + return 0; + } + + Ice::Context ctx; + if(!dictionaryToContext(dict, ctx)) + { + return 0; + } + + (*self->implicitContext)->setContext(ctx); + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextContainsKey(ImplicitContextObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + bool containsKey; + try + { + containsKey = (*self->implicitContext)->containsKey(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyRETURN_BOOL(containsKey); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextGet(ImplicitContextObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + string val; + try + { + val = (*self->implicitContext)->get(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + return createString(val); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextPut(ImplicitContextObject* self, PyObject* args) +{ + PyObject* keyObj; + PyObject* valueObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &keyObj, &valueObj)) + { + return 0; + } + + string key; + string value; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + if(!getStringArg(valueObj, "value", value)) + { + return 0; + } + + string oldVal; + try + { + oldVal = (*self->implicitContext)->put(key, value); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + return createString(oldVal); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +implicitContextRemove(ImplicitContextObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + string val; + try + { + val = (*self->implicitContext)->remove(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + return createString(val); +} + +static PyMethodDef ImplicitContextMethods[] = +{ + { STRCAST("getContext"), reinterpret_cast<PyCFunction>(implicitContextGetContext), METH_VARARGS, + PyDoc_STR(STRCAST("getContext() -> Ice.Context")) }, + { STRCAST("setContext"), reinterpret_cast<PyCFunction>(implicitContextSetContext), METH_VARARGS, + PyDoc_STR(STRCAST("setContext(ctx) -> string")) }, + { STRCAST("containsKey"), reinterpret_cast<PyCFunction>(implicitContextContainsKey), METH_VARARGS, + PyDoc_STR(STRCAST("containsKey(key) -> bool")) }, + { STRCAST("get"), reinterpret_cast<PyCFunction>(implicitContextGet), METH_VARARGS, + PyDoc_STR(STRCAST("get(key) -> string")) }, + { STRCAST("put"), reinterpret_cast<PyCFunction>(implicitContextPut), METH_VARARGS, + PyDoc_STR(STRCAST("put(key, value) -> string")) }, + { STRCAST("remove"), reinterpret_cast<PyCFunction>(implicitContextRemove), METH_VARARGS, + PyDoc_STR(STRCAST("remove(key) -> string")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ImplicitContextType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.ImplicitContext"), /* tp_name */ + sizeof(ImplicitContextObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(implicitContextDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +#if PY_VERSION_HEX >= 0x03000000 + Py_TPFLAGS_DEFAULT, /* tp_flags */ +#else + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_HAVE_RICHCOMPARE, /* tp_flags */ +#endif + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + reinterpret_cast<richcmpfunc>(implicitContextCompare), /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ImplicitContextMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(implicitContextNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initImplicitContext(PyObject* module) +{ + if(PyType_Ready(&ImplicitContextType) < 0) + { + return false; + } + PyTypeObject* type = &ImplicitContextType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ImplicitContext"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createImplicitContext(const Ice::ImplicitContextPtr& implicitContext) +{ + ImplicitContextObject* obj = implicitContextNew(&ImplicitContextType, 0, 0); + if(obj) + { + obj->implicitContext = new Ice::ImplicitContextPtr(implicitContext); + } + return reinterpret_cast<PyObject*>(obj); +} diff --git a/python/modules/IcePy/ImplicitContext.h b/python/modules/IcePy/ImplicitContext.h new file mode 100644 index 00000000000..4301c57a7a7 --- /dev/null +++ b/python/modules/IcePy/ImplicitContext.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_IMPLICIT_CONTEXT_H +#define ICEPY_IMPLICIT_CONTEXT_H + +#include <Config.h> +#include <Ice/ImplicitContext.h> + +namespace IcePy +{ + +extern PyTypeObject ImplicitContextType; + +bool initImplicitContext(PyObject*); + +PyObject* createImplicitContext(const Ice::ImplicitContextPtr&); + +} + +#endif diff --git a/python/modules/IcePy/Init.cpp b/python/modules/IcePy/Init.cpp new file mode 100644 index 00000000000..4de906407c4 --- /dev/null +++ b/python/modules/IcePy/Init.cpp @@ -0,0 +1,244 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <BatchRequestInterceptor.h> +#include <Communicator.h> +#include <Connection.h> +#include <ConnectionInfo.h> +#include <Current.h> +#include <Endpoint.h> +#include <EndpointInfo.h> +#include <ImplicitContext.h> +#include <Logger.h> +#include <ObjectAdapter.h> +#include <Operation.h> +#include <Properties.h> +#include <PropertiesAdmin.h> +#include <Proxy.h> +#include <Slice.h> +#include <Types.h> +#include <Ice/Initialize.h> + +using namespace std; +using namespace IcePy; + +extern "C" PyObject* IcePy_cleanup(PyObject*); + +static PyMethodDef methods[] = +{ + { STRCAST("stringVersion"), reinterpret_cast<PyCFunction>(IcePy_stringVersion), METH_NOARGS, + PyDoc_STR(STRCAST("stringVersion() -> string")) }, + { STRCAST("intVersion"), reinterpret_cast<PyCFunction>(IcePy_intVersion), METH_NOARGS, + PyDoc_STR(STRCAST("intVersion() -> int")) }, + { STRCAST("currentProtocol"), reinterpret_cast<PyCFunction>(IcePy_currentProtocol), METH_NOARGS, + PyDoc_STR(STRCAST("currentProtocol() -> Ice.ProtocolVersion")) }, + { STRCAST("currentProtocolEncoding"), reinterpret_cast<PyCFunction>(IcePy_currentProtocolEncoding), METH_NOARGS, + PyDoc_STR(STRCAST("currentProtocolEncoding() -> Ice.EncodingVersion")) }, + { STRCAST("currentEncoding"), reinterpret_cast<PyCFunction>(IcePy_currentEncoding), METH_NOARGS, + PyDoc_STR(STRCAST("currentEncoding() -> Ice.EncodingVersion")) }, + { STRCAST("stringToProtocolVersion"), reinterpret_cast<PyCFunction>(IcePy_stringToProtocolVersion), METH_VARARGS, + PyDoc_STR(STRCAST("stringToProtocolVersion(str) -> Ice.ProtocolVersion")) }, + { STRCAST("protocolVersionToString"), reinterpret_cast<PyCFunction>(IcePy_protocolVersionToString), METH_VARARGS, + PyDoc_STR(STRCAST("protocolVersionToString(Ice.ProtocolVersion) -> string")) }, + { STRCAST("stringToEncodingVersion"), reinterpret_cast<PyCFunction>(IcePy_stringToEncodingVersion), METH_VARARGS, + PyDoc_STR(STRCAST("stringToEncodingVersion(str) -> Ice.EncodingVersion")) }, + { STRCAST("encodingVersionToString"), reinterpret_cast<PyCFunction>(IcePy_encodingVersionToString), METH_VARARGS, + PyDoc_STR(STRCAST("encodingVersionToString(Ice.EncodingVersion) -> string")) }, + { STRCAST("generateUUID"), reinterpret_cast<PyCFunction>(IcePy_generateUUID), METH_NOARGS, + PyDoc_STR(STRCAST("generateUUID() -> string")) }, + { STRCAST("createProperties"), reinterpret_cast<PyCFunction>(IcePy_createProperties), METH_VARARGS, + PyDoc_STR(STRCAST("createProperties([args]) -> Ice.Properties")) }, + { STRCAST("getProcessLogger"), reinterpret_cast<PyCFunction>(IcePy_getProcessLogger), METH_NOARGS, + PyDoc_STR(STRCAST("getProcessLogger() -> Ice.Logger")) }, + { STRCAST("setProcessLogger"), reinterpret_cast<PyCFunction>(IcePy_setProcessLogger), METH_VARARGS, + PyDoc_STR(STRCAST("setProcessLogger(logger) -> None")) }, + { STRCAST("defineEnum"), reinterpret_cast<PyCFunction>(IcePy_defineEnum), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineStruct"), reinterpret_cast<PyCFunction>(IcePy_defineStruct), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineSequence"), reinterpret_cast<PyCFunction>(IcePy_defineSequence), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineCustom"), reinterpret_cast<PyCFunction>(IcePy_defineCustom), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineDictionary"), reinterpret_cast<PyCFunction>(IcePy_defineDictionary), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("declareProxy"), reinterpret_cast<PyCFunction>(IcePy_declareProxy), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineProxy"), reinterpret_cast<PyCFunction>(IcePy_defineProxy), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("declareClass"), reinterpret_cast<PyCFunction>(IcePy_declareClass), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineClass"), reinterpret_cast<PyCFunction>(IcePy_defineClass), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("defineException"), reinterpret_cast<PyCFunction>(IcePy_defineException), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("stringify"), reinterpret_cast<PyCFunction>(IcePy_stringify), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("stringifyException"), reinterpret_cast<PyCFunction>(IcePy_stringifyException), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("loadSlice"), reinterpret_cast<PyCFunction>(IcePy_loadSlice), METH_VARARGS, + PyDoc_STR(STRCAST("loadSlice(cmd) -> None")) }, + { STRCAST("cleanup"), reinterpret_cast<PyCFunction>(IcePy_cleanup), METH_NOARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("compile"), reinterpret_cast<PyCFunction>(IcePy_compile), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { 0, 0 } /* sentinel */ +}; + +#if PY_VERSION_HEX >= 0x03000000 + +# define INIT_RETURN return(0) + +static struct PyModuleDef iceModule = +{ + PyModuleDef_HEAD_INIT, + "IcePy", + "The Internet Communications Engine.", + -1, + methods, + NULL, + NULL, + NULL, + NULL +}; + +#else + +# define INIT_RETURN return + +PyDoc_STRVAR(moduleDoc, "The Internet Communications Engine."); + +#endif + +#ifdef ICE_STATIC_LIBS +extern "C" +{ +Ice::Plugin* createIceSSL(const Ice::CommunicatorPtr&, const std::string&, const Ice::StringSeq&); +Ice::Plugin* createIceDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&); +Ice::Plugin* createIceLocatorDiscovery(const Ice::CommunicatorPtr&, const string&, const Ice::StringSeq&); +} +#endif + +PyMODINIT_FUNC +#ifndef _WIN32 // On Windows, PyMODINIT_FUNC already defines dllexport +ICE_DECLSPEC_EXPORT +#endif +#if PY_VERSION_HEX >= 0x03000000 +PyInit_IcePy(void) +#else +initIcePy(void) +#endif +{ + PyObject* module; + +#ifdef ICE_STATIC_LIBS + // Register the plugins manually if we're building with static libraries. + Ice::registerPluginFactory("IceSSL", createIceSSL, false); + Ice::registerPluginFactory("IceDiscovery", createIceDiscovery, false); + Ice::registerPluginFactory("IceLocatorDiscovery", createIceLocatorDiscovery, false); +#endif + + // + // Notify Python that we are a multi-threaded extension. + // + PyEval_InitThreads(); + +#if PY_VERSION_HEX >= 0x03000000 + // + // Create the module. + // + module = PyModule_Create(&iceModule); +#else + // + // Initialize the module. + // + module = Py_InitModule3(STRCAST("IcePy"), methods, moduleDoc); +#endif + + // + // Install built-in Ice types. + // + if(!initProxy(module)) + { + INIT_RETURN; + } + if(!initTypes(module)) + { + INIT_RETURN; + } + if(!initProperties(module)) + { + INIT_RETURN; + } + if(!initPropertiesAdmin(module)) + { + INIT_RETURN; + } + if(!initBatchRequest(module)) + { + INIT_RETURN; + } + if(!initCommunicator(module)) + { + INIT_RETURN; + } + if(!initCurrent(module)) + { + INIT_RETURN; + } + if(!initObjectAdapter(module)) + { + INIT_RETURN; + } + if(!initOperation(module)) + { + INIT_RETURN; + } + if(!initLogger(module)) + { + INIT_RETURN; + } + if(!initConnection(module)) + { + INIT_RETURN; + } + if(!initConnectionInfo(module)) + { + INIT_RETURN; + } + if(!initImplicitContext(module)) + { + INIT_RETURN; + } + if(!initEndpoint(module)) + { + INIT_RETURN; + } + if(!initEndpointInfo(module)) + { + INIT_RETURN; + } + +#if PY_VERSION_HEX >= 0x03000000 + return module; +#endif +} + +extern "C" +PyObject* +IcePy_cleanup(PyObject* /*self*/) +{ + cleanupLogger(); + + Py_INCREF(Py_None); + return Py_None; +} diff --git a/python/modules/IcePy/Logger.cpp b/python/modules/IcePy/Logger.cpp new file mode 100644 index 00000000000..e901fb40ed1 --- /dev/null +++ b/python/modules/IcePy/Logger.cpp @@ -0,0 +1,524 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Logger.h> +#include <Thread.h> +#include <Ice/Initialize.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +extern PyTypeObject LoggerType; + +struct LoggerObject +{ + PyObject_HEAD + Ice::LoggerPtr* logger; +}; + +} + +IcePy::LoggerWrapper::LoggerWrapper(PyObject* logger) : + _logger(logger) +{ + Py_INCREF(logger); +} + +void +IcePy::LoggerWrapper::print(const string& message) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + // + // Method must be named "_print". + // + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("_print"), STRCAST("s"), message.c_str()); + if(!tmp.get()) + { + throwPythonException(); + } +} + +void +IcePy::LoggerWrapper::trace(const string& category, const string& message) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("trace"), STRCAST("ss"), category.c_str(), + message.c_str()); + if(!tmp.get()) + { + throwPythonException(); + } +} + +void +IcePy::LoggerWrapper::warning(const string& message) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("warning"), STRCAST("s"), message.c_str()); + if(!tmp.get()) + { + throwPythonException(); + } +} + +void +IcePy::LoggerWrapper::error(const string& message) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("error"), STRCAST("s"), message.c_str()); + if(!tmp.get()) + { + throwPythonException(); + } +} + +string +IcePy::LoggerWrapper::getPrefix() +{ + AdoptThread adoptThread; + + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("getPrefix"), 0); + if(!tmp.get()) + { + throwPythonException(); + } + return getString(tmp.get()); +} + + +Ice::LoggerPtr +IcePy::LoggerWrapper::cloneWithPrefix(const string& prefix) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_logger.get(), STRCAST("cloneWithPrefix"), STRCAST("s"), prefix.c_str()); + if(!tmp.get()) + { + throwPythonException(); + } + + return new LoggerWrapper(tmp.get()); +} + +PyObject* +IcePy::LoggerWrapper::getObject() +{ + return _logger.get(); +} + +#ifdef WIN32 +extern "C" +#endif +static LoggerObject* +loggerNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + LoggerObject* self = reinterpret_cast<LoggerObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->logger = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +loggerDealloc(LoggerObject* self) +{ + delete self->logger; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerPrint(LoggerObject* self, PyObject* args) +{ + PyObject* messageObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &messageObj)) + { + return 0; + } + + string message; + if(!getStringArg(messageObj, "message", message)) + { + return 0; + } + + assert(self->logger); + try + { + (*self->logger)->print(message); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerTrace(LoggerObject* self, PyObject* args) +{ + PyObject* categoryObj; + PyObject* messageObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &categoryObj, &messageObj)) + { + return 0; + } + + string category; + string message; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + if(!getStringArg(messageObj, "message", message)) + { + return 0; + } + + assert(self->logger); + try + { + (*self->logger)->trace(category, message); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerWarning(LoggerObject* self, PyObject* args) +{ + PyObject* messageObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &messageObj)) + { + return 0; + } + + string message; + if(!getStringArg(messageObj, "message", message)) + { + return 0; + } + + assert(self->logger); + try + { + (*self->logger)->warning(message); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerError(LoggerObject* self, PyObject* args) +{ + PyObject* messageObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &messageObj)) + { + return 0; + } + + string message; + if(!getStringArg(messageObj, "message", message)) + { + return 0; + } + + assert(self->logger); + try + { + (*self->logger)->error(message); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerGetPrefix(LoggerObject* self) +{ + string prefix; + + assert(self->logger); + try + { + prefix = (*self->logger)->getPrefix(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(prefix); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +loggerCloneWithPrefix(LoggerObject* self, PyObject* args) +{ + PyObject* prefixObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &prefixObj)) + { + return 0; + } + + string prefix; + if(!getStringArg(prefixObj, "prefix", prefix)) + { + return 0; + } + + Ice::LoggerPtr clone; + + assert(self->logger); + try + { + clone = (*self->logger)->cloneWithPrefix(prefix); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + // + // The new clone can either be a C++ object (such as + // the default logger supplied by the Ice run time), or a C++ + // wrapper around a Python implementation. If the latter, we + // return it directly. Otherwise, we create a Python object + // that delegates to the C++ object. + // + LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(clone); + if(wrapper) + { + PyObject* obj = wrapper->getObject(); + Py_INCREF(obj); + return obj; + } + + return createLogger(clone); +} + +static PyMethodDef LoggerMethods[] = +{ + { STRCAST("_print"), reinterpret_cast<PyCFunction>(loggerPrint), METH_VARARGS, + PyDoc_STR(STRCAST("_print(message) -> None")) }, + { STRCAST("trace"), reinterpret_cast<PyCFunction>(loggerTrace), METH_VARARGS, + PyDoc_STR(STRCAST("trace(category, message) -> None")) }, + { STRCAST("warning"), reinterpret_cast<PyCFunction>(loggerWarning), METH_VARARGS, + PyDoc_STR(STRCAST("warning(message) -> None")) }, + { STRCAST("error"), reinterpret_cast<PyCFunction>(loggerError), METH_VARARGS, + PyDoc_STR(STRCAST("error(message) -> None")) }, + { STRCAST("getPrefix"), reinterpret_cast<PyCFunction>(loggerGetPrefix), METH_NOARGS, + PyDoc_STR(STRCAST("getPrefix() -> string")) }, + { STRCAST("cloneWithPrefix"), reinterpret_cast<PyCFunction>(loggerCloneWithPrefix), METH_VARARGS, + PyDoc_STR(STRCAST("cloneWithPrefix(prefix) -> Ice.Logger")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject LoggerType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Logger"), /* tp_name */ + sizeof(LoggerObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(loggerDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + LoggerMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(loggerNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initLogger(PyObject* module) +{ + if(PyType_Ready(&LoggerType) < 0) + { + return false; + } + PyTypeObject* type = &LoggerType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Logger"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +void +IcePy::cleanupLogger() +{ + // + // Python is about to exit; we need to remove the wrapper around the process logger. + // + Ice::setProcessLogger(0); +} + +PyObject* +IcePy::createLogger(const Ice::LoggerPtr& logger) +{ + LoggerObject* obj = loggerNew(&LoggerType, 0, 0); + if(obj) + { + obj->logger = new Ice::LoggerPtr(logger); + } + return reinterpret_cast<PyObject*>(obj); +} + +extern "C" +PyObject* +IcePy_getProcessLogger(PyObject* /*self*/) +{ + Ice::LoggerPtr logger; + try + { + logger = Ice::getProcessLogger(); + } + catch(const Ice::Exception& ex) + { + IcePy::setPythonException(ex); + return 0; + } + + // + // The process logger can either be a C++ object (such as + // the default logger supplied by the Ice run time), or a C++ + // wrapper around a Python implementation. If the latter, we + // return it directly. Otherwise, we create a Python object + // that delegates to the C++ object. + // + LoggerWrapperPtr wrapper = LoggerWrapperPtr::dynamicCast(logger); + if(wrapper) + { + PyObject* obj = wrapper->getObject(); + Py_INCREF(obj); + return obj; + } + + return createLogger(logger); +} + +extern "C" +PyObject* +IcePy_setProcessLogger(PyObject* /*self*/, PyObject* args) +{ + PyObject* loggerType = lookupType("Ice.Logger"); + assert(loggerType); + + PyObject* logger; + if(!PyArg_ParseTuple(args, STRCAST("O!"), loggerType, &logger)) + { + return 0; + } + + Ice::LoggerPtr wrapper = new LoggerWrapper(logger); + try + { + Ice::setProcessLogger(wrapper); + } + catch(const Ice::Exception& ex) + { + IcePy::setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} diff --git a/python/modules/IcePy/Logger.h b/python/modules/IcePy/Logger.h new file mode 100644 index 00000000000..5e8b15a9daa --- /dev/null +++ b/python/modules/IcePy/Logger.h @@ -0,0 +1,57 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_LOGGER_H +#define ICEPY_LOGGER_H + +#include <Config.h> +#include <Util.h> +#include <Ice/Logger.h> + +namespace IcePy +{ + +// +// LoggerWrapper delegates to a Python implementation. +// +class LoggerWrapper : public Ice::Logger +{ +public: + + LoggerWrapper(PyObject*); + + virtual void print(const std::string&); + virtual void trace(const std::string&, const std::string&); + virtual void warning(const std::string&); + virtual void error(const std::string&); + virtual std::string getPrefix(); + virtual Ice::LoggerPtr cloneWithPrefix(const std::string&); + PyObject* getObject(); + +private: + + PyObjectHandle _logger; +}; +typedef IceUtil::Handle<LoggerWrapper> LoggerWrapperPtr; + +bool initLogger(PyObject*); + +void cleanupLogger(); + +// +// Create a Python object that delegates to a C++ implementation. +// +PyObject* createLogger(const Ice::LoggerPtr&); + +} + +extern "C" PyObject* IcePy_getProcessLogger(PyObject*); +extern "C" PyObject* IcePy_setProcessLogger(PyObject*, PyObject*); + +#endif diff --git a/python/modules/IcePy/Makefile b/python/modules/IcePy/Makefile new file mode 100644 index 00000000000..3efba732368 --- /dev/null +++ b/python/modules/IcePy/Makefile @@ -0,0 +1,58 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +LIBFILENAME = $(call mkpylibfilename,IcePy,$(VERSION)) +SONAME = $(call mkpysoname,IcePy,$(SOVERSION)) +LIBNAME = $(call mkpylibname,IcePy) + +TARGETS = $(call mklibtargets,$(libdir)/$(LIBFILENAME),$(libdir)/$(SONAME),$(libdir)/$(LIBNAME)) + +OBJS = BatchRequestInterceptor.o \ + Communicator.o \ + Connection.o \ + ConnectionInfo.o \ + Current.o \ + Endpoint.o \ + EndpointInfo.o \ + ImplicitContext.o \ + Init.o \ + Logger.o \ + ObjectAdapter.o \ + ObjectFactory.o \ + Operation.o \ + Properties.o \ + PropertiesAdmin.o \ + Proxy.o \ + Slice.o \ + Thread.o \ + Types.o \ + Util.o + +include $(top_srcdir)/config/Make.rules + +CPPFLAGS := -I. $(CPPFLAGS) $(ICE_FLAGS) $(PYTHON_FLAGS) + +LINKWITH := $(ICE_LIBS) $(PYTHON_LIBS) $(CXXLIBS) + +$(libdir)/$(LIBFILENAME): $(OBJS) + rm -f $@ + $(call mkshlib,$@,$(SONAME),$(OBJS),$(LINKWITH)) + +$(libdir)/$(SONAME): $(libdir)/$(LIBFILENAME) + rm -f $@ + ln -s $(LIBFILENAME) $@ + +$(libdir)/$(LIBNAME): $(libdir)/$(SONAME) + rm -f $@ + ln -s $(SONAME) $@ + +install:: all + $(call installlib,$(DESTDIR)$(install_libdir),$(libdir),$(LIBFILENAME),$(SONAME),$(LIBNAME)) diff --git a/python/modules/IcePy/Makefile.mak b/python/modules/IcePy/Makefile.mak new file mode 100644 index 00000000000..f39e162a31d --- /dev/null +++ b/python/modules/IcePy/Makefile.mak @@ -0,0 +1,72 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ..\.. + +LIBNAME = IcePy$(PYLIBSUFFIX).lib +DLLNAME = $(top_srcdir)\python\IcePy$(PYLIBSUFFIX).pyd + +TARGETS = $(LIBNAME) $(DLLNAME) + +OBJS = .\BatchRequestInterceptor.obj \ + .\Communicator.obj \ + .\Connection.obj \ + .\ConnectionInfo.obj \ + .\Current.obj \ + .\Endpoint.obj \ + .\EndpointInfo.obj \ + .\ImplicitContext.obj \ + .\Init.obj \ + .\Logger.obj \ + .\ObjectAdapter.obj \ + .\ObjectFactory.obj \ + .\Operation.obj \ + .\Properties.obj \ + .\PropertiesAdmin.obj \ + .\Proxy.obj \ + .\Slice.obj \ + .\Thread.obj \ + .\Types.obj \ + .\Util.obj + +# +# Get Make.common.rules.mak to figure out CPP_COMPILER by setting it +# to "auto" +# +CPP_COMPILER=auto + +!include $(top_srcdir)\config\Make.rules.mak + +# +# Ensure we're using VC100 +# +!if "$(CPP_COMPILER)" != "VC100" +!error Invalid CPP_COMPILER setting: $(CPP_COMPILER). Must be set to VC100. +!endif + +CPPFLAGS = -I. $(CPPFLAGS) $(ICE_CPPFLAGS) $(PYTHON_CPPFLAGS) + +LINKWITH = $(ICE_LIBS) $(PYTHON_LIBS) $(CXXLIBS) + +$(LIBNAME): $(DLLNAME) + +$(DLLNAME): $(OBJS) IcePy.res + $(LINK) $(PYTHON_LDFLAGS) $(ICE_LDFLAGS) $(LD_DLLFLAGS) $(PDBFLAGS) $(OBJS) \ + $(PREOUT)$@ $(PRELIBS)$(LINKWITH) IcePy.res + move $(@:.pyd=.lib) $(LIBNAME) + @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \ + $(MT) -nologo -manifest $@.manifest -outputresource:$@;#2 && del /q $@.manifest + @if exist $(@:.pyd=.exp) del /q $(@:.pyd=.exp) + + +clean:: + -del /q IcePy.res + +install:: all + copy $(DLLNAME) "$(install_libdir)" diff --git a/python/modules/IcePy/ObjectAdapter.cpp b/python/modules/IcePy/ObjectAdapter.cpp new file mode 100644 index 00000000000..f57c58884d1 --- /dev/null +++ b/python/modules/IcePy/ObjectAdapter.cpp @@ -0,0 +1,1841 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <ObjectAdapter.h> +#include <Communicator.h> +#include <Current.h> +#include <Endpoint.h> +#include <Operation.h> +#include <Proxy.h> +#include <Thread.h> +#include <Types.h> +#include <Util.h> +#include <Ice/Communicator.h> +#include <Ice/LocalException.h> +#include <Ice/Locator.h> +#include <Ice/ObjectAdapter.h> +#include <Ice/Router.h> +#include <Ice/ServantLocator.h> + +#include <pythread.h> + +using namespace std; +using namespace IcePy; + +static long _mainThreadId; + +namespace IcePy +{ + +typedef InvokeThread<Ice::ObjectAdapter> AdapterInvokeThread; +typedef IceUtil::Handle<AdapterInvokeThread> AdapterInvokeThreadPtr; + +struct ObjectAdapterObject +{ + PyObject_HEAD + Ice::ObjectAdapterPtr* adapter; + IceUtil::Monitor<IceUtil::Mutex>* deactivateMonitor; + AdapterInvokeThreadPtr* deactivateThread; + bool deactivated; + IceUtil::Monitor<IceUtil::Mutex>* holdMonitor; + AdapterInvokeThreadPtr* holdThread; + bool held; +}; + +class ServantLocatorWrapper : public Ice::ServantLocator +{ +public: + + ServantLocatorWrapper(PyObject*); + ~ServantLocatorWrapper(); + + virtual Ice::ObjectPtr locate(const Ice::Current&, Ice::LocalObjectPtr&); + + virtual void finished(const Ice::Current&, const Ice::ObjectPtr&, const Ice::LocalObjectPtr&); + + virtual void deactivate(const string&); + + PyObject* getObject(); + +private: + + // + // This object is created in locate() and destroyed after finished(). + // + struct Cookie : public Ice::LocalObject + { + Cookie(); + ~Cookie(); + + PyObject* current; + ServantWrapperPtr servant; + PyObject* cookie; + }; + typedef IceUtil::Handle<Cookie> CookiePtr; + + PyObject* _locator; + PyObject* _objectType; +}; +typedef IceUtil::Handle<ServantLocatorWrapper> ServantLocatorWrapperPtr; + +} + +namespace +{ + +bool getServantWrapper(PyObject* servant, ServantWrapperPtr& wrapper) +{ + PyObject* objectType = lookupType("Ice.Object"); + if(servant != Py_None && !PyObject_IsInstance(servant, objectType)) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected Ice object or None")); + return false; + } + + if(servant != Py_None) + { + wrapper = createServantWrapper(servant); + if(PyErr_Occurred()) + { + return false; + } + } + + return true; +} + +} + +// +// ServantLocatorWrapper implementation. +// +IcePy::ServantLocatorWrapper::ServantLocatorWrapper(PyObject* locator) : + _locator(locator) +{ + Py_INCREF(_locator); + _objectType = lookupType("Ice.Object"); +} + +IcePy::ServantLocatorWrapper::~ServantLocatorWrapper() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + Py_DECREF(_locator); +} + +Ice::ObjectPtr +IcePy::ServantLocatorWrapper::locate(const Ice::Current& current, Ice::LocalObjectPtr& cookie) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + CookiePtr c = new Cookie; + c->current = createCurrent(current); + if(!c->current) + { + throwPythonException(); + } + + // + // Invoke locate on the Python object. We expect the object to + // return either the servant by itself, or the servant in a tuple + // with an optional cookie object. + // + PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("locate"), STRCAST("O"), c->current); + if(PyErr_Occurred()) + { + PyException ex; // Retrieve the exception before another Python API call clears it. + + // + // A locator that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + PyObject* userExceptionType = lookupType("Ice.UserException"); + if(PyObject_IsInstance(ex.ex.get(), userExceptionType)) + { + throw ExceptionWriter(current.adapter->getCommunicator(), ex.ex); + } + + ex.raise(); + } + + if(res.get() == Py_None) + { + return 0; + } + + PyObject* servantObj = 0; + PyObject* cookieObj = Py_None; + if(PyTuple_Check(res.get())) + { + if(PyTuple_GET_SIZE(res.get()) > 2) + { + PyErr_Warn(PyExc_RuntimeWarning, STRCAST("invalid return value for ServantLocator::locate")); + return 0; + } + servantObj = PyTuple_GET_ITEM(res.get(), 0); + if(PyTuple_GET_SIZE(res.get()) > 1) + { + cookieObj = PyTuple_GET_ITEM(res.get(), 1); + } + } + else + { + servantObj = res.get(); + } + + // + // Verify that the servant is an Ice object. + // + if(!PyObject_IsInstance(servantObj, _objectType)) + { + PyErr_Warn(PyExc_RuntimeWarning, STRCAST("return value of ServantLocator::locate is not an Ice object")); + return 0; + } + + // + // Save state in our cookie and return a wrapper for the servant. + // + c->servant = createServantWrapper(servantObj); + c->cookie = cookieObj; + Py_INCREF(c->cookie); + cookie = c; + return c->servant; +} + +void +IcePy::ServantLocatorWrapper::finished(const Ice::Current& current, const Ice::ObjectPtr&, + const Ice::LocalObjectPtr& cookie) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + CookiePtr c = CookiePtr::dynamicCast(cookie); + assert(c); + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(c->servant); + PyObjectHandle servantObj = wrapper->getObject(); + + PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("finished"), STRCAST("OOO"), c->current, + servantObj.get(), c->cookie); + if(PyErr_Occurred()) + { + PyException ex; // Retrieve the exception before another Python API call clears it. + + // + // A locator that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + PyObject* userExceptionType = lookupType("Ice.UserException"); + if(PyObject_IsInstance(ex.ex.get(), userExceptionType)) + { + throw ExceptionWriter(current.adapter->getCommunicator(), ex.ex); + } + + ex.raise(); + } +} + +void +IcePy::ServantLocatorWrapper::deactivate(const string& category) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle res = PyObject_CallMethod(_locator, STRCAST("deactivate"), STRCAST("s"), category.c_str()); + if(PyErr_Occurred()) + { + PyException ex; // Retrieve the exception before another Python API call clears it. + + // + // A locator that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + ex.raise(); + } +} + +PyObject* +IcePy::ServantLocatorWrapper::getObject() +{ + Py_INCREF(_locator); + return _locator; +} + +IcePy::ServantLocatorWrapper::Cookie::Cookie() +{ + current = 0; + cookie = 0; +} + +IcePy::ServantLocatorWrapper::Cookie::~Cookie() +{ + AdoptThread adoptThread; + Py_XDECREF(current); + Py_XDECREF(cookie); +} + +#ifdef WIN32 +extern "C" +#endif +static ObjectAdapterObject* +adapterNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("Use communicator.createObjectAdapter to create an adapter")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +adapterDealloc(ObjectAdapterObject* self) +{ + if(self->deactivateThread) + { + (*self->deactivateThread)->getThreadControl().join(); + } + if(self->holdThread) + { + (*self->holdThread)->getThreadControl().join(); + } + delete self->adapter; + delete self->deactivateMonitor; + delete self->deactivateThread; + delete self->holdMonitor; + delete self->holdThread; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterGetName(ObjectAdapterObject* self) +{ + assert(self->adapter); + string name; + try + { + name = (*self->adapter)->getName(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(name); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterGetCommunicator(ObjectAdapterObject* self) +{ + assert(self->adapter); + Ice::CommunicatorPtr communicator; + try + { + communicator = (*self->adapter)->getCommunicator(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createCommunicator(communicator); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterActivate(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->activate(); + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*self->holdMonitor); + self->held = false; + if(self->holdThread) + { + (*self->holdThread)->getThreadControl().join(); + delete self->holdThread; + self->holdThread = 0; + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterHold(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + (*self->adapter)->hold(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterWaitForHold(ObjectAdapterObject* self, PyObject* args) +{ + // + // This method differs somewhat from the standard Ice API because of + // signal issues. This method expects an integer timeout value, and + // returns a boolean to indicate whether it was successful. When + // called from the main thread, the timeout is used to allow control + // to return to the caller (the Python interpreter) periodically. + // When called from any other thread, we call waitForHold directly + // and ignore the timeout. + // + int timeout = 0; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(timeout > 0); + assert(self->adapter); + + // + // Do not call waitForHold from the main thread, because it prevents + // signals (such as keyboard interrupts) from being delivered to Python. + // + if(PyThread_get_thread_ident() == _mainThreadId) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*self->holdMonitor); + + if(!self->held) + { + if(self->holdThread == 0) + { + AdapterInvokeThreadPtr t = new AdapterInvokeThread(*self->adapter, + &Ice::ObjectAdapter::waitForHold, + *self->holdMonitor, self->held); + self->holdThread = new AdapterInvokeThreadPtr(t); + t->start(); + } + + bool done; + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + done = (*self->holdMonitor).timedWait(IceUtil::Time::milliSeconds(timeout)); + } + + if(!done) + { + PyRETURN_FALSE; + } + } + + assert(self->held); + + Ice::Exception* ex = (*self->holdThread)->getException(); + if(ex) + { + setPythonException(*ex); + return 0; + } + } + else + { + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->waitForHold(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + } + + PyRETURN_TRUE; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterDeactivate(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->deactivate(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterWaitForDeactivate(ObjectAdapterObject* self, PyObject* args) +{ + // + // This method differs somewhat from the standard Ice API because of + // signal issues. This method expects an integer timeout value, and + // returns a boolean to indicate whether it was successful. When + // called from the main thread, the timeout is used to allow control + // to return to the caller (the Python interpreter) periodically. + // When called from any other thread, we call waitForDeactivate directly + // and ignore the timeout. + // + int timeout = 0; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(timeout > 0); + assert(self->adapter); + + // + // Do not call waitForDeactivate from the main thread, because it prevents + // signals (such as keyboard interrupts) from being delivered to Python. + // + if(PyThread_get_thread_ident() == _mainThreadId) + { + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(*self->deactivateMonitor); + + if(!self->deactivated) + { + if(self->deactivateThread == 0) + { + AdapterInvokeThreadPtr t = new AdapterInvokeThread(*self->adapter, + &Ice::ObjectAdapter::waitForDeactivate, + *self->deactivateMonitor, self->deactivated); + self->deactivateThread = new AdapterInvokeThreadPtr(t); + t->start(); + } + + while(!self->deactivated) + { + bool done; + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + done = (*self->deactivateMonitor).timedWait(IceUtil::Time::milliSeconds(timeout)); + } + + if(!done) + { + PyRETURN_FALSE; + } + } + } + + assert(self->deactivated); + + Ice::Exception* ex = (*self->deactivateThread)->getException(); + if(ex) + { + setPythonException(*ex); + return 0; + } + } + else + { + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->waitForDeactivate(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + } + + PyRETURN_TRUE; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterIsDeactivated(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + (*self->adapter)->isDeactivated(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterDestroy(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->destroy(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAdd(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* servant; + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("OO!"), &servant, identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + ServantWrapperPtr wrapper; + if(!getServantWrapper(servant, wrapper)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->add(wrapper, ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAddFacet(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* servant; + PyObject* id; + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("OO!O"), &servant, identityType, &id, &facetObj)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + ServantWrapperPtr wrapper; + if(!getServantWrapper(servant, wrapper)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->addFacet(wrapper, ident, facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAddWithUUID(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* servant; + if(!PyArg_ParseTuple(args, STRCAST("O"), &servant)) + { + return 0; + } + + ServantWrapperPtr wrapper; + if(!getServantWrapper(servant, wrapper)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->addWithUUID(wrapper); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAddFacetWithUUID(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* servant; + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &servant, &facetObj)) + { + return 0; + } + + ServantWrapperPtr wrapper; + if(!getServantWrapper(servant, wrapper)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->addFacetWithUUID(wrapper, facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAddDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* servant; + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &servant, &categoryObj)) + { + return 0; + } + + ServantWrapperPtr wrapper; + if(!getServantWrapper(servant, wrapper)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + try + { + (*self->adapter)->addDefaultServant(wrapper, category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRemove(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->remove(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRemoveFacet(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), identityType, &id, &facetObj)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->removeFacet(ident, facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRemoveAllFacets(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::FacetMap facetMap; + try + { + facetMap = (*self->adapter)->removeAllFacets(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(!result.get()) + { + return 0; + } + + for(Ice::FacetMap::iterator p = facetMap.begin(); p != facetMap.end(); ++p) + { + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(p->second); + assert(wrapper); + PyObjectHandle obj = wrapper->getObject(); + if(PyDict_SetItemString(result.get(), const_cast<char*>(p->first.c_str()), obj.get()) < 0) + { + return 0; + } + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRemoveDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->removeDefaultServant(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFind(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->find(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFindFacet(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), identityType, &id, &facetObj)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->findFacet(ident, facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFindAllFacets(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::FacetMap facetMap; + try + { + facetMap = (*self->adapter)->findAllFacets(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(!result.get()) + { + return 0; + } + + for(Ice::FacetMap::iterator p = facetMap.begin(); p != facetMap.end(); ++p) + { + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(p->second); + assert(wrapper); + PyObjectHandle obj = wrapper->getObject(); + if(PyDict_SetItemString(result.get(), const_cast<char*>(p->first.c_str()), obj.get()) < 0) + { + return 0; + } + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFindByProxy(ObjectAdapterObject* self, PyObject* args) +{ + // + // We don't want to accept None here, so we can specify ProxyType and force + // the caller to supply a proxy object. + // + PyObject* proxy; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &ProxyType, &proxy)) + { + return 0; + } + + Ice::ObjectPrx prx = getProxy(proxy); + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->findByProxy(prx); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFindDefaultServant(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPtr obj; + try + { + obj = (*self->adapter)->findDefaultServant(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!obj) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantWrapperPtr wrapper = ServantWrapperPtr::dynamicCast(obj); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterAddServantLocator(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* locatorType = lookupType("Ice.ServantLocator"); + PyObject* locator; + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O!O"), locatorType, &locator, &categoryObj)) + { + return 0; + } + + ServantLocatorWrapperPtr wrapper = new ServantLocatorWrapper(locator); + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + assert(self->adapter); + try + { + (*self->adapter)->addServantLocator(wrapper, category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRemoveServantLocator(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ServantLocatorPtr locator; + try + { + locator = (*self->adapter)->removeServantLocator(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!locator) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantLocatorWrapperPtr wrapper = ServantLocatorWrapperPtr::dynamicCast(locator); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterFindServantLocator(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* categoryObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &categoryObj)) + { + return 0; + } + + string category; + if(!getStringArg(categoryObj, "category", category)) + { + return 0; + } + + assert(self->adapter); + Ice::ServantLocatorPtr locator; + try + { + locator = (*self->adapter)->findServantLocator(category); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!locator) + { + Py_INCREF(Py_None); + return Py_None; + } + + ServantLocatorWrapperPtr wrapper = ServantLocatorWrapperPtr::dynamicCast(locator); + assert(wrapper); + return wrapper->getObject(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterCreateProxy(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->createProxy(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterCreateDirectProxy(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->createDirectProxy(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterCreateIndirectProxy(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + assert(self->adapter); + Ice::ObjectPrx proxy; + try + { + proxy = (*self->adapter)->createIndirectProxy(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(proxy, (*self->adapter)->getCommunicator()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterSetLocator(ObjectAdapterObject* self, PyObject* args) +{ + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O"), &p)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "setLocator", "loc", proxy, "Ice.LocatorPrx")) + { + return 0; + } + + Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + + assert(self->adapter); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->setLocator(locator); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterGetLocator(ObjectAdapterObject* self) +{ + assert(self->adapter); + Ice::LocatorPrx locator; + try + { + locator = (*self->adapter)->getLocator(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!locator) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* locatorProxyType = lookupType("Ice.LocatorPrx"); + assert(locatorProxyType); + return createProxy(locator, (*self->adapter)->getCommunicator(), locatorProxyType); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterRefreshPublishedEndpoints(ObjectAdapterObject* self) +{ + assert(self->adapter); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + (*self->adapter)->refreshPublishedEndpoints(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterGetEndpoints(ObjectAdapterObject* self) +{ + assert(self->adapter); + + Ice::EndpointSeq endpoints; + try + { + endpoints = (*self->adapter)->getEndpoints(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + int count = static_cast<int>(endpoints.size()); + PyObjectHandle result = PyTuple_New(count); + int i = 0; + for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++i) + { + PyObjectHandle endp = createEndpoint(*p); + if(!endp.get()) + { + return 0; + } + PyTuple_SET_ITEM(result.get(), i, endp.release()); // PyTuple_SET_ITEM steals a reference. + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +adapterGetPublishedEndpoints(ObjectAdapterObject* self) +{ + assert(self->adapter); + + Ice::EndpointSeq endpoints; + try + { + endpoints = (*self->adapter)->getPublishedEndpoints(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + int count = static_cast<int>(endpoints.size()); + PyObjectHandle result = PyTuple_New(count); + int i = 0; + for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++i) + { + PyObjectHandle endp = createEndpoint(*p); + if(!endp.get()) + { + return 0; + } + PyTuple_SET_ITEM(result.get(), i, endp.release()); // PyTuple_SET_ITEM steals a reference. + } + + return result.release(); +} + +static PyMethodDef AdapterMethods[] = +{ + { STRCAST("getName"), reinterpret_cast<PyCFunction>(adapterGetName), METH_NOARGS, + PyDoc_STR(STRCAST("getName() -> string")) }, + { STRCAST("getCommunicator"), reinterpret_cast<PyCFunction>(adapterGetCommunicator), METH_NOARGS, + PyDoc_STR(STRCAST("getCommunicator() -> Ice.Communicator")) }, + { STRCAST("activate"), reinterpret_cast<PyCFunction>(adapterActivate), METH_NOARGS, + PyDoc_STR(STRCAST("activate() -> None")) }, + { STRCAST("hold"), reinterpret_cast<PyCFunction>(adapterHold), METH_NOARGS, + PyDoc_STR(STRCAST("hold() -> None")) }, + { STRCAST("waitForHold"), reinterpret_cast<PyCFunction>(adapterWaitForHold), METH_VARARGS, + PyDoc_STR(STRCAST("waitForHold() -> None")) }, + { STRCAST("deactivate"), reinterpret_cast<PyCFunction>(adapterDeactivate), METH_NOARGS, + PyDoc_STR(STRCAST("deactivate() -> None")) }, + { STRCAST("waitForDeactivate"), reinterpret_cast<PyCFunction>(adapterWaitForDeactivate), METH_VARARGS, + PyDoc_STR(STRCAST("waitForDeactivate() -> None")) }, + { STRCAST("isDeactivated"), reinterpret_cast<PyCFunction>(adapterIsDeactivated), METH_NOARGS, + PyDoc_STR(STRCAST("isDeactivatied() -> None")) }, + { STRCAST("destroy"), reinterpret_cast<PyCFunction>(adapterDestroy), METH_NOARGS, + PyDoc_STR(STRCAST("destroy() -> None")) }, + { STRCAST("add"), reinterpret_cast<PyCFunction>(adapterAdd), METH_VARARGS, + PyDoc_STR(STRCAST("add(servant, identity) -> Ice.ObjectPrx")) }, + { STRCAST("addFacet"), reinterpret_cast<PyCFunction>(adapterAddFacet), METH_VARARGS, + PyDoc_STR(STRCAST("addFacet(servant, identity, facet) -> Ice.ObjectPrx")) }, + { STRCAST("addWithUUID"), reinterpret_cast<PyCFunction>(adapterAddWithUUID), METH_VARARGS, + PyDoc_STR(STRCAST("addWithUUID(servant) -> Ice.ObjectPrx")) }, + { STRCAST("addFacetWithUUID"), reinterpret_cast<PyCFunction>(adapterAddFacetWithUUID), METH_VARARGS, + PyDoc_STR(STRCAST("addFacetWithUUID(servant, facet) -> Ice.ObjectPrx")) }, + { STRCAST("addDefaultServant"), reinterpret_cast<PyCFunction>(adapterAddDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("addDefaultServant(servant, category) -> None")) }, + { STRCAST("remove"), reinterpret_cast<PyCFunction>(adapterRemove), METH_VARARGS, + PyDoc_STR(STRCAST("remove(identity) -> Ice.Object")) }, + { STRCAST("removeFacet"), reinterpret_cast<PyCFunction>(adapterRemoveFacet), METH_VARARGS, + PyDoc_STR(STRCAST("removeFacet(identity, facet) -> Ice.Object")) }, + { STRCAST("removeAllFacets"), reinterpret_cast<PyCFunction>(adapterRemoveAllFacets), METH_VARARGS, + PyDoc_STR(STRCAST("removeAllFacets(identity) -> dictionary")) }, + { STRCAST("removeDefaultServant"), reinterpret_cast<PyCFunction>(adapterRemoveDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("removeDefaultServant(category) -> Ice.Object")) }, + { STRCAST("find"), reinterpret_cast<PyCFunction>(adapterFind), METH_VARARGS, + PyDoc_STR(STRCAST("find(identity) -> Ice.Object")) }, + { STRCAST("findFacet"), reinterpret_cast<PyCFunction>(adapterFindFacet), METH_VARARGS, + PyDoc_STR(STRCAST("findFacet(identity, facet) -> Ice.Object")) }, + { STRCAST("findAllFacets"), reinterpret_cast<PyCFunction>(adapterFindAllFacets), METH_VARARGS, + PyDoc_STR(STRCAST("findAllFacets(identity) -> dictionary")) }, + { STRCAST("findByProxy"), reinterpret_cast<PyCFunction>(adapterFindByProxy), METH_VARARGS, + PyDoc_STR(STRCAST("findByProxy(Ice.ObjectPrx) -> Ice.Object")) }, + { STRCAST("findDefaultServant"), reinterpret_cast<PyCFunction>(adapterFindDefaultServant), METH_VARARGS, + PyDoc_STR(STRCAST("findDefaultServant(category) -> Ice.Object")) }, + { STRCAST("addServantLocator"), reinterpret_cast<PyCFunction>(adapterAddServantLocator), METH_VARARGS, + PyDoc_STR(STRCAST("addServantLocator(Ice.ServantLocator, category) -> None")) }, + { STRCAST("removeServantLocator"), reinterpret_cast<PyCFunction>(adapterRemoveServantLocator), METH_VARARGS, + PyDoc_STR(STRCAST("removeServantLocator(category) -> Ice.ServantLocator")) }, + { STRCAST("findServantLocator"), reinterpret_cast<PyCFunction>(adapterFindServantLocator), METH_VARARGS, + PyDoc_STR(STRCAST("findServantLocator(category) -> Ice.ServantLocator")) }, + { STRCAST("createProxy"), reinterpret_cast<PyCFunction>(adapterCreateProxy), METH_VARARGS, + PyDoc_STR(STRCAST("createProxy(identity) -> Ice.ObjectPrx")) }, + { STRCAST("createDirectProxy"), reinterpret_cast<PyCFunction>(adapterCreateDirectProxy), METH_VARARGS, + PyDoc_STR(STRCAST("createDirectProxy(identity) -> Ice.ObjectPrx")) }, + { STRCAST("createIndirectProxy"), reinterpret_cast<PyCFunction>(adapterCreateIndirectProxy), METH_VARARGS, + PyDoc_STR(STRCAST("createIndirectProxy(identity) -> Ice.ObjectPrx")) }, + { STRCAST("setLocator"), reinterpret_cast<PyCFunction>(adapterSetLocator), METH_VARARGS, + PyDoc_STR(STRCAST("setLocator(proxy) -> None")) }, + { STRCAST("getLocator"), reinterpret_cast<PyCFunction>(adapterGetLocator), METH_NOARGS, + PyDoc_STR(STRCAST("getLocator() -> Ice.LocatorPrx")) }, + { STRCAST("refreshPublishedEndpoints"), reinterpret_cast<PyCFunction>(adapterRefreshPublishedEndpoints), METH_NOARGS, + PyDoc_STR(STRCAST("refreshPublishedEndpoints() -> None")) }, + { STRCAST("getEndpoints"), reinterpret_cast<PyCFunction>(adapterGetEndpoints), METH_NOARGS, + PyDoc_STR(STRCAST("getEndpoints() -> None")) }, + { STRCAST("getPublishedEndpoints"), reinterpret_cast<PyCFunction>(adapterGetPublishedEndpoints), METH_NOARGS, + PyDoc_STR(STRCAST("getPublishedEndpoints() -> None")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ObjectAdapterType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.ObjectAdapter"), /* tp_name */ + sizeof(ObjectAdapterObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(adapterDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + AdapterMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(adapterNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initObjectAdapter(PyObject* module) +{ + _mainThreadId = PyThread_get_thread_ident(); + + if(PyType_Ready(&ObjectAdapterType) < 0) + { + return false; + } + PyTypeObject* type = &ObjectAdapterType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ObjectAdapter"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createObjectAdapter(const Ice::ObjectAdapterPtr& adapter) +{ + ObjectAdapterObject* obj = + reinterpret_cast<ObjectAdapterObject*>(ObjectAdapterType.tp_alloc(&ObjectAdapterType, 0)); + if(obj) + { + obj->adapter = new Ice::ObjectAdapterPtr(adapter); + obj->deactivateMonitor = new IceUtil::Monitor<IceUtil::Mutex>; + obj->deactivateThread = 0; + obj->deactivated = false; + obj->holdMonitor = new IceUtil::Monitor<IceUtil::Mutex>; + obj->holdThread = 0; + obj->held = false; + } + return reinterpret_cast<PyObject*>(obj); +} + +Ice::ObjectAdapterPtr +IcePy::getObjectAdapter(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&ObjectAdapterType))); + ObjectAdapterObject* oaobj = reinterpret_cast<ObjectAdapterObject*>(obj); + return *oaobj->adapter; +} + +PyObject* +IcePy::wrapObjectAdapter(const Ice::ObjectAdapterPtr& adapter) +{ + // + // Create an Ice.ObjectAdapter wrapper for IcePy.ObjectAdapter. + // + PyObjectHandle adapterI = createObjectAdapter(adapter); + if(!adapterI.get()) + { + return 0; + } + PyObject* wrapperType = lookupType("Ice.ObjectAdapterI"); + assert(wrapperType); + PyObjectHandle args = PyTuple_New(1); + if(!args.get()) + { + return 0; + } + PyTuple_SET_ITEM(args.get(), 0, adapterI.release()); + return PyObject_Call(wrapperType, args.get(), 0); +} + +Ice::ObjectAdapterPtr +IcePy::unwrapObjectAdapter(PyObject* obj) +{ +#ifndef NDEBUG + PyObject* wrapperType = lookupType("Ice.ObjectAdapterI"); +#endif + assert(wrapperType); + assert(PyObject_IsInstance(obj, wrapperType)); + PyObjectHandle impl = PyObject_GetAttrString(obj, STRCAST("_impl")); + assert(impl.get()); + return getObjectAdapter(impl.get()); +} diff --git a/python/modules/IcePy/ObjectAdapter.h b/python/modules/IcePy/ObjectAdapter.h new file mode 100644 index 00000000000..22edc82c929 --- /dev/null +++ b/python/modules/IcePy/ObjectAdapter.h @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_OBJECT_ADAPTER_H +#define ICEPY_OBJECT_ADAPTER_H + +#include <Config.h> +#include <Ice/ObjectAdapterF.h> + +namespace IcePy +{ + +extern PyTypeObject ObjectAdapterType; + +bool initObjectAdapter(PyObject*); + +PyObject* createObjectAdapter(const Ice::ObjectAdapterPtr&); +Ice::ObjectAdapterPtr getObjectAdapter(PyObject*); + +PyObject* wrapObjectAdapter(const Ice::ObjectAdapterPtr&); +Ice::ObjectAdapterPtr unwrapObjectAdapter(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/ObjectFactory.cpp b/python/modules/IcePy/ObjectFactory.cpp new file mode 100644 index 00000000000..1829d32956b --- /dev/null +++ b/python/modules/IcePy/ObjectFactory.cpp @@ -0,0 +1,196 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <ObjectFactory.h> +#include <Thread.h> +#include <Types.h> +#include <Util.h> +#include <Ice/LocalException.h> + +using namespace std; +using namespace IcePy; + +IcePy::ObjectFactory::ObjectFactory() +{ +} + +IcePy::ObjectFactory::~ObjectFactory() +{ + assert(_factoryMap.empty()); +} + +Ice::ObjectPtr +IcePy::ObjectFactory::create(const string& id) +{ + PyObject* factory = 0; + + // + // Check if the application has registered a factory for this id. + // + { + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p != _factoryMap.end()) + { + factory = p->second; + } + } + + // + // Get the type information. + // + ClassInfoPtr info; + if(id == Ice::Object::ice_staticId()) + { + // + // When the ID is that of Ice::Object, it indicates that the stream has not + // found a factory and is providing us an opportunity to preserve the object. + // + info = lookupClassInfo("::Ice::UnknownSlicedObject"); + } + else + { + info = lookupClassInfo(id); + } + + if(!info) + { + return 0; + } + + if(factory) + { + // + // Invoke the create method on the Python factory object. + // + PyObjectHandle obj = PyObject_CallMethod(factory, STRCAST("create"), STRCAST("s"), id.c_str()); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + if(obj.get() == Py_None) + { + return 0; + } + return new ObjectReader(obj.get(), info); + } + + // + // If the requested type is an abstract class, then we give up. + // + if(info->isAbstract) + { + return 0; + } + + // + // Instantiate the object. + // + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(info->pythonType.get()); + PyObjectHandle args = PyTuple_New(0); + PyObjectHandle obj = type->tp_new(type, args.get(), 0); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + return new ObjectReader(obj.get(), info); +} + +void +IcePy::ObjectFactory::destroy() +{ + FactoryMap factories; + + { + Lock sync(*this); + factories = _factoryMap; + _factoryMap.clear(); + } + + // + // We release the GIL before calling communicator->destroy(), so we must + // reacquire it before calling back into Python. + // + AdoptThread adoptThread; + + for(FactoryMap::iterator p = factories.begin(); p != factories.end(); ++p) + { + // + // Invoke the destroy method on each registered Python factory. + // + PyObjectHandle obj = PyObject_CallMethod(p->second, STRCAST("destroy"), 0); + PyErr_Clear(); // Ignore errors. + Py_DECREF(p->second); + } +} + +bool +IcePy::ObjectFactory::add(PyObject* factory, const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p != _factoryMap.end()) + { + Ice::AlreadyRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object factory"; + ex.id = id; + setPythonException(ex); + return false; + } + + _factoryMap.insert(FactoryMap::value_type(id, factory)); + Py_INCREF(factory); + + return true; +} + +bool +IcePy::ObjectFactory::remove(const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p == _factoryMap.end()) + { + Ice::NotRegisteredException ex(__FILE__, __LINE__); + ex.kindOfObject = "object factory"; + ex.id = id; + setPythonException(ex); + return false; + } + + Py_DECREF(p->second); + _factoryMap.erase(p); + + return true; +} + +PyObject* +IcePy::ObjectFactory::find(const string& id) +{ + Lock sync(*this); + + FactoryMap::iterator p = _factoryMap.find(id); + if(p == _factoryMap.end()) + { + Py_INCREF(Py_None); + return Py_None; + } + + Py_INCREF(p->second); + return p->second; +} diff --git a/python/modules/IcePy/ObjectFactory.h b/python/modules/IcePy/ObjectFactory.h new file mode 100644 index 00000000000..8445996b330 --- /dev/null +++ b/python/modules/IcePy/ObjectFactory.h @@ -0,0 +1,50 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_OBJECT_FACTORY_H +#define ICEPY_OBJECT_FACTORY_H + +#include <Config.h> +#include <Ice/ObjectF.h> +#include <Ice/ObjectFactory.h> +#include <IceUtil/Mutex.h> + +namespace IcePy +{ + +// +// Each communicator registers an instance of ObjectFactory as its +// default object factory. This instance delegates to registered Python +// objects, and instantiates concrete classes when no factory is present. +// +class ObjectFactory : public Ice::ObjectFactory, public IceUtil::Mutex +{ +public: + + ObjectFactory(); + ~ObjectFactory(); + + virtual Ice::ObjectPtr create(const std::string&); + + virtual void destroy(); + + bool add(PyObject*, const std::string&); + bool remove(const std::string&); + PyObject* find(const std::string&); + +private: + + typedef std::map<std::string, PyObject*> FactoryMap; + FactoryMap _factoryMap; +}; +typedef IceUtil::Handle<ObjectFactory> ObjectFactoryPtr; + +} + +#endif diff --git a/python/modules/IcePy/Operation.cpp b/python/modules/IcePy/Operation.cpp new file mode 100644 index 00000000000..5ca673898f4 --- /dev/null +++ b/python/modules/IcePy/Operation.cpp @@ -0,0 +1,4219 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Operation.h> +#include <Communicator.h> +#include <Current.h> +#include <Proxy.h> +#include <Thread.h> +#include <Types.h> +#include <Connection.h> +#include <Util.h> +#include <Ice/Communicator.h> +#include <Ice/IncomingAsync.h> +#include <Ice/Initialize.h> +#include <Ice/LocalException.h> +#include <Ice/Logger.h> +#include <Ice/ObjectAdapter.h> +#include <Ice/AsyncResult.h> +#include <Ice/Properties.h> +#include <Ice/Proxy.h> +#include <Slice/PythonUtil.h> + +using namespace std; +using namespace IcePy; +using namespace Slice::Python; + +namespace IcePy +{ + +// +// Information about an operation's parameter. +// +class ParamInfo : public UnmarshalCallback +{ +public: + + virtual void unmarshaled(PyObject*, PyObject*, void*); + + Ice::StringSeq metaData; + TypeInfoPtr type; + bool optional; + int tag; + int pos; +}; +typedef IceUtil::Handle<ParamInfo> ParamInfoPtr; +typedef list<ParamInfoPtr> ParamInfoList; + +// +// Encapsulates attributes of an operation. +// +class Operation : public IceUtil::Shared +{ +public: + + Operation(const char*, PyObject*, PyObject*, int, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*, PyObject*); + + void deprecate(const string&); + + string name; + Ice::OperationMode mode; + Ice::OperationMode sendMode; + bool amd; + Ice::FormatType format; + Ice::StringSeq metaData; + ParamInfoList inParams; + ParamInfoList optionalInParams; + ParamInfoList outParams; + ParamInfoList optionalOutParams; + ParamInfoPtr returnType; + ExceptionInfoList exceptions; + string dispatchName; + bool sendsClasses; + bool returnsClasses; + bool pseudoOp; + +private: + + string _deprecateMessage; + + static void convertParams(PyObject*, ParamInfoList&, int, bool&); + static ParamInfoPtr convertParam(PyObject*, int); +}; +typedef IceUtil::Handle<Operation> OperationPtr; + +// +// The base class for client-side invocations. +// +class Invocation : virtual public IceUtil::Shared +{ +public: + + Invocation(const Ice::ObjectPrx&); + + virtual PyObject* invoke(PyObject*, PyObject* = 0) = 0; + +protected: + + Ice::ObjectPrx _prx; +}; +typedef IceUtil::Handle<Invocation> InvocationPtr; + +// +// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal +// parameters and exceptions. +// +class TypedInvocation : virtual public Invocation +{ +public: + + TypedInvocation(const Ice::ObjectPrx&, const OperationPtr&); + +protected: + + OperationPtr _op; + Ice::CommunicatorPtr _communicator; + + enum MappingType { SyncMapping, AsyncMapping, OldAsyncMapping }; + + bool prepareRequest(PyObject*, MappingType, Ice::OutputStreamPtr&, pair<const Ice::Byte*, const Ice::Byte*>&); + PyObject* unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>&); + PyObject* unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>&); + bool validateException(PyObject*) const; + void checkTwowayOnly(const Ice::ObjectPrx&) const; +}; + +// +// Synchronous typed invocation. +// +class SyncTypedInvocation : virtual public TypedInvocation +{ +public: + + SyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); +}; + +// +// Asynchronous typed invocation. +// +class AsyncTypedInvocation : virtual public TypedInvocation +{ +public: + + AsyncTypedInvocation(const Ice::ObjectPrx&, PyObject*, const OperationPtr&); + ~AsyncTypedInvocation(); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); + PyObject* end(const Ice::ObjectPrx&, const OperationPtr&, const Ice::AsyncResultPtr&); + + string opName() const; + + void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&); + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + void checkAsyncTwowayOnly(const Ice::ObjectPrx&) const; + + PyObject* _pyProxy; + PyObject* _response; + PyObject* _ex; + PyObject* _sent; +}; +typedef IceUtil::Handle<AsyncTypedInvocation> AsyncTypedInvocationPtr; + +// +// Old-style asynchronous typed invocation. +// +class OldAsyncTypedInvocation : virtual public TypedInvocation +{ +public: + + OldAsyncTypedInvocation(const Ice::ObjectPrx&, const OperationPtr&); + ~OldAsyncTypedInvocation(); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); + + void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&); + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + PyObject* _callback; +}; + +// +// Synchronous blobject invocation. +// +class SyncBlobjectInvocation : virtual public Invocation +{ +public: + + SyncBlobjectInvocation(const Ice::ObjectPrx&); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); +}; + +// +// Asynchronous blobject invocation. +// +class AsyncBlobjectInvocation : virtual public Invocation +{ +public: + + AsyncBlobjectInvocation(const Ice::ObjectPrx&, PyObject*); + ~AsyncBlobjectInvocation(); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); + PyObject* end(const Ice::ObjectPrx&, const Ice::AsyncResultPtr&); + + void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&); + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + PyObject* _pyProxy; + string _op; + PyObject* _response; + PyObject* _ex; + PyObject* _sent; +}; +typedef IceUtil::Handle<AsyncBlobjectInvocation> AsyncBlobjectInvocationPtr; + +// +// Old-style asynchronous blobject invocation. +// +class OldAsyncBlobjectInvocation : virtual public Invocation +{ +public: + + OldAsyncBlobjectInvocation(const Ice::ObjectPrx&); + ~OldAsyncBlobjectInvocation(); + + virtual PyObject* invoke(PyObject*, PyObject* = 0); + + void response(bool, const pair<const Ice::Byte*, const Ice::Byte*>&); + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + string _op; + PyObject* _callback; +}; + +// +// The base class for server-side upcalls. +// +class Upcall : virtual public IceUtil::Shared +{ +public: + + virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&) = 0; + virtual void response(PyObject*, const Ice::EncodingVersion&) = 0; + virtual void exception(PyException&, const Ice::EncodingVersion&) = 0; +}; +typedef IceUtil::Handle<Upcall> UpcallPtr; + +// +// TypedInvocation uses the information in the given Operation to validate, marshal, and unmarshal +// parameters and exceptions. +// +class TypedUpcall : virtual public Upcall +{ +public: + + TypedUpcall(const OperationPtr&, const Ice::AMD_Object_ice_invokePtr&, const Ice::CommunicatorPtr&); + + virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); + virtual void response(PyObject*, const Ice::EncodingVersion&); + virtual void exception(PyException&, const Ice::EncodingVersion&); + +private: + + bool validateException(PyObject*) const; + + OperationPtr _op; + Ice::AMD_Object_ice_invokePtr _callback; + Ice::CommunicatorPtr _communicator; + bool _finished; +}; + +// +// Upcall for blobject servants. +// +class BlobjectUpcall : virtual public Upcall +{ +public: + + BlobjectUpcall(bool, const Ice::AMD_Object_ice_invokePtr&); + + virtual void dispatch(PyObject*, const pair<const Ice::Byte*, const Ice::Byte*>&, const Ice::Current&); + virtual void response(PyObject*, const Ice::EncodingVersion&); + virtual void exception(PyException&, const Ice::EncodingVersion&); + +private: + + bool _amd; + Ice::AMD_Object_ice_invokePtr _callback; + bool _finished; +}; + +// +// TypedServantWrapper uses the information in Operation to validate, marshal, and unmarshal +// parameters and exceptions. +// +class TypedServantWrapper : public ServantWrapper +{ +public: + + TypedServantWrapper(PyObject*); + + virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, + const pair<const Ice::Byte*, const Ice::Byte*>&, + const Ice::Current&); + +private: + + typedef map<string, OperationPtr> OperationMap; + OperationMap _operationMap; + OperationMap::iterator _lastOp; +}; + +// +// Encapsulates a blobject servant. +// +class BlobjectServantWrapper : public ServantWrapper +{ +public: + + BlobjectServantWrapper(PyObject*, bool); + + virtual void ice_invoke_async(const Ice::AMD_Object_ice_invokePtr&, + const pair<const Ice::Byte*, const Ice::Byte*>&, + const Ice::Current&); + +private: + + bool _amd; +}; + +struct OperationObject +{ + PyObject_HEAD + OperationPtr* op; +}; + +struct AMDCallbackObject +{ + PyObject_HEAD + UpcallPtr* upcall; + Ice::EncodingVersion encoding; +}; + +struct AsyncResultObject +{ + PyObject_HEAD + Ice::AsyncResultPtr* result; + InvocationPtr* invocation; + PyObject* proxy; + PyObject* connection; + PyObject* communicator; +}; + +extern PyTypeObject OperationType; +extern PyTypeObject AMDCallbackType; + +class UserExceptionReaderFactoryI : public Ice::UserExceptionReaderFactory +{ +public: + + UserExceptionReaderFactoryI(const Ice::CommunicatorPtr& communicator) : + _communicator(communicator) + { + } + + virtual void createAndThrow(const string& id) const + { + ExceptionInfoPtr info = lookupExceptionInfo(id); + if(info) + { + throw ExceptionReader(_communicator, info); + } + } + +private: + + const Ice::CommunicatorPtr _communicator; +}; + +} + +namespace +{ + +OperationPtr +getOperation(PyObject* p) +{ + assert(PyObject_IsInstance(p, reinterpret_cast<PyObject*>(&OperationType)) == 1); + OperationObject* obj = reinterpret_cast<OperationObject*>(p); + return *obj->op; +} + +void +handleException() +{ + assert(PyErr_Occurred()); + + PyException ex; // Retrieve it before another Python API call clears it. + + // + // A callback that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + ex.raise(); +} + +void +callException(PyObject* method, PyObject* ex) +{ + PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), ex); + PyObjectHandle tmp = PyObject_Call(method, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } +} + +void +callException(PyObject* method, const Ice::Exception& ex) +{ + PyObjectHandle exh = convertException(ex); + assert(exh.get()); + callException(method, exh.get()); +} + +void +callException(PyObject* callback, const string& op, const string& method, PyObject* ex) +{ + if(!PyObject_HasAttrString(callback, STRCAST(method.c_str()))) + { + ostringstream ostr; + ostr << "AMI callback object for operation `" << op << "' does not define " << method << "()"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } + else + { + PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str())); + assert(m.get()); + callException(m.get(), ex); + } +} + +void +callException(PyObject* callback, const string& op, const string& method, const Ice::Exception& ex) +{ + PyObjectHandle exh = convertException(ex); + assert(exh.get()); + callException(callback, op, method, exh.get()); +} + +void +callSent(PyObject* method, bool sentSynchronously, bool passArg) +{ + PyObjectHandle args; + if(passArg) + { + args = Py_BuildValue(STRCAST("(O)"), sentSynchronously ? getTrue() : getFalse()); + } + else + { + args = PyTuple_New(0); + } + PyObjectHandle tmp = PyObject_Call(method, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } +} + +void +callSent(PyObject* callback, const string& method, bool sentSynchronously, bool passArg) +{ + if(PyObject_HasAttrString(callback, STRCAST(method.c_str()))) + { + PyObjectHandle m = PyObject_GetAttrString(callback, STRCAST(method.c_str())); + assert(m.get()); + callSent(m.get(), sentSynchronously, passArg); + } +} + +} + +#ifdef WIN32 +extern "C" +#endif +static OperationObject* +operationNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + OperationObject* self = reinterpret_cast<OperationObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->op = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static int +operationInit(OperationObject* self, PyObject* args, PyObject* /*kwds*/) +{ + char* name; + PyObject* modeType = lookupType("Ice.OperationMode"); + assert(modeType); + PyObject* mode; + PyObject* sendMode; + int amd; + PyObject* format; + PyObject* metaData; + PyObject* inParams; + PyObject* outParams; + PyObject* returnType; + PyObject* exceptions; + if(!PyArg_ParseTuple(args, STRCAST("sO!O!iOO!O!O!OO!"), &name, modeType, &mode, modeType, &sendMode, &amd, + &format, &PyTuple_Type, &metaData, &PyTuple_Type, &inParams, &PyTuple_Type, &outParams, + &returnType, &PyTuple_Type, &exceptions)) + { + return -1; + } + + OperationPtr op = new Operation(name, mode, sendMode, amd, format, metaData, inParams, outParams, returnType, + exceptions); + self->op = new OperationPtr(op); + + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +operationDealloc(OperationObject* self) +{ + delete self->op; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +operationInvoke(OperationObject* self, PyObject* args) +{ + PyObject* pyProxy; + PyObject* opArgs; + if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &pyProxy, &PyTuple_Type, &opArgs)) + { + return 0; + } + + Ice::ObjectPrx prx = getProxy(pyProxy); + assert(self->op); + + InvocationPtr i = new SyncTypedInvocation(prx, *self->op); + return i->invoke(opArgs); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +operationInvokeAsync(OperationObject* self, PyObject* args) +{ + PyObject* pyProxy; + PyObject* opArgs; + if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &pyProxy, &PyTuple_Type, &opArgs)) + { + return 0; + } + + Ice::ObjectPrx prx = getProxy(pyProxy); + assert(self->op); + + InvocationPtr i = new OldAsyncTypedInvocation(prx, *self->op); + return i->invoke(opArgs); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +operationBegin(OperationObject* self, PyObject* args) +{ + PyObject* proxy; + PyObject* opArgs; + if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &proxy, &PyTuple_Type, &opArgs)) + { + return 0; + } + + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new AsyncTypedInvocation(p, proxy, *self->op); + return i->invoke(opArgs); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +operationEnd(OperationObject* self, PyObject* args) +{ + PyObject* proxy; + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!O!"), &ProxyType, &proxy, &AsyncResultType, &result)) + { + return 0; + } + + AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result); + assert(ar); + AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*ar->invocation); + if(!i) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_%s"), + (*self->op)->name.c_str()); + return 0; + } + Ice::ObjectPrx p = getProxy(proxy); + return i->end(p, *self->op, *ar->result); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +operationDeprecate(OperationObject* self, PyObject* args) +{ + char* msg; + if(!PyArg_ParseTuple(args, STRCAST("s"), &msg)) + { + return 0; + } + + assert(self->op); + (*self->op)->deprecate(msg); + + Py_INCREF(Py_None); + return Py_None; +} + +// +// AMDCallback operations +// + +#ifdef WIN32 +extern "C" +#endif +static AMDCallbackObject* +amdCallbackNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + AMDCallbackObject* self = reinterpret_cast<AMDCallbackObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->upcall = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +amdCallbackDealloc(AMDCallbackObject* self) +{ + delete self->upcall; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +amdCallbackIceResponse(AMDCallbackObject* self, PyObject* args) +{ + try + { + assert(self->upcall); + (*self->upcall)->response(args, self->encoding); + } + catch(...) + { + // + // No exceptions should propagate to Python. + // + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +amdCallbackIceException(AMDCallbackObject* self, PyObject* args) +{ + PyObject* ex; + if(!PyArg_ParseTuple(args, STRCAST("O"), &ex)) + { + return 0; + } + + if(!PyObject_IsInstance(ex, PyExc_Exception)) + { + PyErr_Format(PyExc_TypeError, "ice_exception argument is not an exception"); + return 0; + } + + try + { + assert(self->upcall); + PyException pye(ex); // No traceback information available. + (*self->upcall)->exception(pye, self->encoding); + } + catch(...) + { + // + // No exceptions should propagate to Python. + // + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +// +// AsyncResult operations +// + +#ifdef WIN32 +extern "C" +#endif +static AsyncResultObject* +asyncResultNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + AsyncResultObject* self = reinterpret_cast<AsyncResultObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->result = 0; + self->invocation = 0; + self->proxy = 0; + self->connection = 0; + self->communicator = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +asyncResultDealloc(AsyncResultObject* self) +{ + delete self->result; + delete self->invocation; + Py_XDECREF(self->proxy); + Py_XDECREF(self->connection); + Py_XDECREF(self->communicator); + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultGetCommunicator(AsyncResultObject* self) +{ + if(self->communicator) + { + Py_INCREF(self->communicator); + return self->communicator; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultCancel(AsyncResultObject* self) +{ + try + { + (*self->result)->cancel(); + } + catch(...) + { + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultGetConnection(AsyncResultObject* self) +{ + if(self->connection) + { + Py_INCREF(self->connection); + return self->connection; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultGetProxy(AsyncResultObject* self) +{ + if(self->proxy) + { + Py_INCREF(self->proxy); + return self->proxy; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultIsCompleted(AsyncResultObject* self) +{ + bool b = false; + + try + { + assert(self->result); + b = (*self->result)->isCompleted(); + } + catch(...) + { + assert(false); + } + + PyRETURN_BOOL(b); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultWaitForCompleted(AsyncResultObject* self) +{ + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + try + { + assert(self->result); + (*self->result)->waitForCompleted(); + } + catch(...) + { + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultIsSent(AsyncResultObject* self) +{ + bool b = false; + + try + { + assert(self->result); + b = (*self->result)->isSent(); + } + catch(...) + { + assert(false); + } + + PyRETURN_BOOL(b); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultWaitForSent(AsyncResultObject* self) +{ + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + try + { + assert(self->result); + (*self->result)->waitForSent(); + } + catch(...) + { + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultThrowLocalException(AsyncResultObject* self) +{ + try + { + assert(self->result); + (*self->result)->throwLocalException(); + } + catch(const Ice::LocalException& ex) + { + setPythonException(ex); + return 0; + } + catch(...) + { + assert(false); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultSentSynchronously(AsyncResultObject* self) +{ + bool b = false; + + try + { + assert(self->result); + b = (*self->result)->sentSynchronously(); + } + catch(...) + { + assert(false); + } + + PyRETURN_BOOL(b); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +asyncResultGetOperation(AsyncResultObject* self) +{ + string op; + + try + { + // + // Since the extension uses the Blobject API, calling (*self->result)->getOperation() + // always returns "ice_invoke" as the operation name. If the caller used a regular + // (typed) proxy method, we obtain the actual operation name from the invocation. + // + if(self->invocation) + { + AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*self->invocation); + if(i) + { + op = i->opName(); + } + } + if(op.empty()) + { + assert(self->result); + op = (*self->result)->getOperation(); + } + } + catch(...) + { + assert(false); + } + + return createString(op); +} + +// +// ParamInfo implementation. +// +void +IcePy::ParamInfo::unmarshaled(PyObject* val, PyObject* target, void* closure) +{ + assert(PyTuple_Check(target)); + long i = reinterpret_cast<long>(closure); + PyTuple_SET_ITEM(target, i, val); + Py_INCREF(val); // PyTuple_SET_ITEM steals a reference. +} + +// +// Operation implementation. +// +IcePy::Operation::Operation(const char* n, PyObject* m, PyObject* sm, int amdFlag, PyObject* fmt, PyObject* meta, + PyObject* in, PyObject* out, PyObject* ret, PyObject* ex) +{ + name = n; + + // + // mode + // + PyObjectHandle modeValue = PyObject_GetAttrString(m, STRCAST("value")); + mode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get())); + assert(!PyErr_Occurred()); + + // + // sendMode + // + PyObjectHandle sendModeValue = PyObject_GetAttrString(sm, STRCAST("value")); + sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(sendModeValue.get())); + assert(!PyErr_Occurred()); + + // + // amd + // + amd = amdFlag ? true : false; + if(amd) + { + dispatchName = name + "_async"; + } + else + { + dispatchName = fixIdent(name); + } + + // + // format + // + if(fmt == Py_None) + { + format = Ice::DefaultFormat; + } + else + { + PyObjectHandle formatValue = PyObject_GetAttrString(fmt, STRCAST("value")); + format = (Ice::FormatType)static_cast<int>(PyLong_AsLong(formatValue.get())); + assert(!PyErr_Occurred()); + } + + // + // metaData + // + assert(PyTuple_Check(meta)); +#ifndef NDEBUG + bool b = +#endif + tupleToStringSeq(meta, metaData); + assert(b); + + // + // returnType + // + returnsClasses = false; + if(ret != Py_None) + { + returnType = convertParam(ret, 0); + if(!returnType->optional) + { + returnsClasses = returnType->type->usesClasses(); + } + } + + // + // inParams + // + sendsClasses = false; + convertParams(in, inParams, 0, sendsClasses); + + // + // outParams + // + convertParams(out, outParams, returnType ? 1 : 0, returnsClasses); + + class SortFn + { + public: + static bool compare(const ParamInfoPtr& lhs, const ParamInfoPtr& rhs) + { + return lhs->tag < rhs->tag; + } + + static bool isRequired(const ParamInfoPtr& i) + { + return !i->optional; + } + }; + + // + // The inParams list represents the parameters in the order of declaration. + // We also need a sorted list of optional parameters. + // + ParamInfoList l = inParams; + copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalInParams)); + optionalInParams.sort(SortFn::compare); + + // + // The outParams list represents the parameters in the order of declaration. + // We also need a sorted list of optional parameters. If the return value is + // optional, we must include it in this list. + // + l = outParams; + copy(l.begin(), remove_if(l.begin(), l.end(), SortFn::isRequired), back_inserter(optionalOutParams)); + if(returnType && returnType->optional) + { + optionalOutParams.push_back(returnType); + } + optionalOutParams.sort(SortFn::compare); + + // + // exceptions + // + Py_ssize_t sz = PyTuple_GET_SIZE(ex); + for(Py_ssize_t i = 0; i < sz; ++i) + { + exceptions.push_back(getException(PyTuple_GET_ITEM(ex, i))); + } + + // + // Does the operation name start with "ice_"? + // + pseudoOp = name.find("ice_") == 0; +} + +void +IcePy::Operation::deprecate(const string& msg) +{ + if(!msg.empty()) + { + _deprecateMessage = msg; + } + else + { + _deprecateMessage = "operation " + name + " is deprecated"; + } +} + +void +IcePy::Operation::convertParams(PyObject* p, ParamInfoList& params, int posOffset, bool& usesClasses) +{ + int sz = static_cast<int>(PyTuple_GET_SIZE(p)); + for(int i = 0; i < sz; ++i) + { + PyObject* item = PyTuple_GET_ITEM(p, i); + ParamInfoPtr param = convertParam(item, i + posOffset); + params.push_back(param); + if(!param->optional && !usesClasses) + { + usesClasses = param->type->usesClasses(); + } + } +} + +ParamInfoPtr +IcePy::Operation::convertParam(PyObject* p, int pos) +{ + assert(PyTuple_Check(p)); + assert(PyTuple_GET_SIZE(p) == 4); + + ParamInfoPtr param = new ParamInfo; + + // + // metaData + // + PyObject* meta = PyTuple_GET_ITEM(p, 0); + assert(PyTuple_Check(meta)); +#ifndef NDEBUG + bool b = +#endif + tupleToStringSeq(meta, param->metaData); + assert(b); + + // + // type + // + PyObject* type = PyTuple_GET_ITEM(p, 1); + if(type != Py_None) + { + param->type = getType(type); + } + + // + // optional + // + param->optional = PyObject_IsTrue(PyTuple_GET_ITEM(p, 2)) == 1; + + // + // tag + // + param->tag = static_cast<int>(PyLong_AsLong(PyTuple_GET_ITEM(p, 3))); + + // + // position + // + param->pos = pos; + + return param; +} + +static PyMethodDef OperationMethods[] = +{ + { STRCAST("invoke"), reinterpret_cast<PyCFunction>(operationInvoke), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("invokeAsync"), reinterpret_cast<PyCFunction>(operationInvokeAsync), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("begin"), reinterpret_cast<PyCFunction>(operationBegin), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("end"), reinterpret_cast<PyCFunction>(operationEnd), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("deprecate"), reinterpret_cast<PyCFunction>(operationDeprecate), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMethodDef AMDCallbackMethods[] = +{ + { STRCAST("ice_response"), reinterpret_cast<PyCFunction>(amdCallbackIceResponse), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { STRCAST("ice_exception"), reinterpret_cast<PyCFunction>(amdCallbackIceException), METH_VARARGS, + PyDoc_STR(STRCAST("internal function")) }, + { 0, 0 } /* sentinel */ +}; + +static PyMethodDef AsyncResultMethods[] = +{ + { STRCAST("cancel"), reinterpret_cast<PyCFunction>(asyncResultCancel), METH_NOARGS, + PyDoc_STR(STRCAST("cancels the invocation")) }, + { STRCAST("getCommunicator"), reinterpret_cast<PyCFunction>(asyncResultGetCommunicator), METH_NOARGS, + PyDoc_STR(STRCAST("returns the communicator for the invocation")) }, + { STRCAST("getConnection"), reinterpret_cast<PyCFunction>(asyncResultGetConnection), METH_NOARGS, + PyDoc_STR(STRCAST("returns the connection for the invocation")) }, + { STRCAST("getProxy"), reinterpret_cast<PyCFunction>(asyncResultGetProxy), METH_NOARGS, + PyDoc_STR(STRCAST("returns the proxy for the invocation")) }, + { STRCAST("isCompleted"), reinterpret_cast<PyCFunction>(asyncResultIsCompleted), METH_NOARGS, + PyDoc_STR(STRCAST("returns true if the request is complete")) }, + { STRCAST("waitForCompleted"), reinterpret_cast<PyCFunction>(asyncResultWaitForCompleted), METH_NOARGS, + PyDoc_STR(STRCAST("blocks until the request is complete")) }, + { STRCAST("isSent"), reinterpret_cast<PyCFunction>(asyncResultIsSent), METH_NOARGS, + PyDoc_STR(STRCAST("returns true if the request is sent")) }, + { STRCAST("waitForSent"), reinterpret_cast<PyCFunction>(asyncResultWaitForSent), METH_NOARGS, + PyDoc_STR(STRCAST("blocks until the request is sent")) }, + { STRCAST("throwLocalException"), reinterpret_cast<PyCFunction>(asyncResultThrowLocalException), METH_NOARGS, + PyDoc_STR(STRCAST("throw location exception if the request failed with a local exception")) }, + { STRCAST("sentSynchronously"), reinterpret_cast<PyCFunction>(asyncResultSentSynchronously), METH_NOARGS, + PyDoc_STR(STRCAST("returns true if the request was sent synchronously")) }, + { STRCAST("getOperation"), reinterpret_cast<PyCFunction>(asyncResultGetOperation), METH_NOARGS, + PyDoc_STR(STRCAST("returns the name of the operation")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject OperationType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Operation"), /* tp_name */ + sizeof(OperationObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(operationDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + OperationMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + reinterpret_cast<initproc>(operationInit), /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(operationNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject AMDCallbackType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.AMDCallback"), /* tp_name */ + sizeof(AMDCallbackObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(amdCallbackDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + AMDCallbackMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(amdCallbackNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject AsyncResultType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.AsyncResult"), /* tp_name */ + sizeof(AsyncResultObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(asyncResultDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + AsyncResultMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(asyncResultNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initOperation(PyObject* module) +{ + if(PyType_Ready(&OperationType) < 0) + { + return false; + } + PyTypeObject* opType = &OperationType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Operation"), reinterpret_cast<PyObject*>(opType)) < 0) + { + return false; + } + + if(PyType_Ready(&AMDCallbackType) < 0) + { + return false; + } + PyTypeObject* cbType = &AMDCallbackType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("AMDCallback"), reinterpret_cast<PyObject*>(cbType)) < 0) + { + return false; + } + + if(PyType_Ready(&AsyncResultType) < 0) + { + return false; + } + PyTypeObject* arType = &AsyncResultType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("AsyncResult"), reinterpret_cast<PyObject*>(arType)) < 0) + { + return false; + } + + return true; +} + +// +// Invocation +// +IcePy::Invocation::Invocation(const Ice::ObjectPrx& prx) : + _prx(prx) +{ +} + +// +// TypedInvocation +// +IcePy::TypedInvocation::TypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) : + Invocation(prx), _op(op), _communicator(prx->ice_getCommunicator()) +{ +} + +bool +IcePy::TypedInvocation::prepareRequest(PyObject* args, MappingType mapping, Ice::OutputStreamPtr& os, + pair<const Ice::Byte*, const Ice::Byte*>& params) +{ + assert(PyTuple_Check(args)); + params.first = params.second = static_cast<const Ice::Byte*>(0); + + // + // Validate the number of arguments. + // + Py_ssize_t argc = PyTuple_GET_SIZE(args); + Py_ssize_t paramCount = static_cast<Py_ssize_t>(_op->inParams.size()); + if(argc != paramCount) + { + string opName; + if(mapping == OldAsyncMapping) + { + opName = _op->name + "_async"; + } + else if(mapping == AsyncMapping) + { + opName = "begin_" + _op->name; + } + else + { + opName = fixIdent(_op->name); + } + PyErr_Format(PyExc_RuntimeError, STRCAST("%s expects %d in parameters"), opName.c_str(), + static_cast<int>(paramCount)); + return false; + } + + if(!_op->inParams.empty()) + { + try + { + // + // Marshal the in parameters. + // + os = Ice::createOutputStream(_communicator); + os->startEncapsulation(_prx->ice_getEncodingVersion(), _op->format); + + ObjectMap objectMap; + ParamInfoList::iterator p; + + // + // Validate the supplied arguments. + // + for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p) + { + ParamInfoPtr info = *p; + PyObject* arg = PyTuple_GET_ITEM(args, info->pos); + if((!info->optional || arg != Unset) && !info->type->validate(arg)) + { + string name; + if(mapping == OldAsyncMapping) + { + name = _op->name + "_async"; + } + else if(mapping == AsyncMapping) + { + name = "begin_" + _op->name; + } + else + { + name = fixIdent(_op->name); + } + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for argument %d in operation `%s'"), + mapping == OldAsyncMapping ? info->pos + 2 : info->pos + 1, + const_cast<char*>(name.c_str())); + return false; + } + } + + // + // Marshal the required parameters. + // + for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(!info->optional) + { + PyObject* arg = PyTuple_GET_ITEM(args, info->pos); + info->type->marshal(arg, os, &objectMap, false, &info->metaData); + } + } + + // + // Marshal the optional parameters. + // + for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p) + { + ParamInfoPtr info = *p; + PyObject* arg = PyTuple_GET_ITEM(args, info->pos); + if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat())) + { + info->type->marshal(arg, os, &objectMap, true, &info->metaData); + } + } + + if(_op->sendsClasses) + { + os->writePendingObjects(); + } + + os->endEncapsulation(); + params = os->finished(); + } + catch(const AbortMarshaling&) + { + assert(PyErr_Occurred()); + return false; + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return false; + } + } + + return true; +} + +PyObject* +IcePy::TypedInvocation::unmarshalResults(const pair<const Ice::Byte*, const Ice::Byte*>& bytes) +{ + Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size()); + if(_op->returnType) + { + numResults++; + } + + PyObjectHandle results = PyTuple_New(numResults); + if(results.get() && numResults > 0) + { + Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, bytes); + + // + // Store a pointer to a local SlicedDataUtil object as the stream's closure. + // This is necessary to support object unmarshaling (see ObjectReader). + // + SlicedDataUtil util; + assert(!is->closure()); + is->closure(&util); + + is->startEncapsulation(); + + ParamInfoList::iterator p; + + // + // Unmarshal the required out parameters. + // + for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(!info->optional) + { + void* closure = reinterpret_cast<void*>(info->pos); + info->type->unmarshal(is, info, results.get(), closure, false, &info->metaData); + } + } + + // + // Unmarshal the required return value, if any. + // + if(_op->returnType && !_op->returnType->optional) + { + assert(_op->returnType->pos == 0); + void* closure = reinterpret_cast<void*>(_op->returnType->pos); + _op->returnType->type->unmarshal(is, _op->returnType, results.get(), closure, false, &_op->metaData); + } + + // + // Unmarshal the optional results. This includes an optional return value. + // + for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(is->readOptional(info->tag, info->type->optionalFormat())) + { + void* closure = reinterpret_cast<void*>(info->pos); + info->type->unmarshal(is, info, results.get(), closure, true, &info->metaData); + } + else + { + if(PyTuple_SET_ITEM(results.get(), info->pos, Unset) < 0) + { + return 0; + } + Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference. + } + } + + if(_op->returnsClasses) + { + is->readPendingObjects(); + } + + is->endEncapsulation(); + + util.update(); + } + + return results.release(); +} + +PyObject* +IcePy::TypedInvocation::unmarshalException(const pair<const Ice::Byte*, const Ice::Byte*>& bytes) +{ + Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, bytes); + + // + // Store a pointer to a local SlicedDataUtil object as the stream's closure. + // This is necessary to support object unmarshaling (see ObjectReader). + // + SlicedDataUtil util; + assert(!is->closure()); + is->closure(&util); + + is->startEncapsulation(); + + try + { + Ice::UserExceptionReaderFactoryPtr factory = new UserExceptionReaderFactoryI(_communicator); + is->throwException(factory); + } + catch(const ExceptionReader& r) + { + is->endEncapsulation(); + + PyObject* ex = r.getException(); + + if(validateException(ex)) + { + util.update(); + + Ice::SlicedDataPtr slicedData = r.getSlicedData(); + if(slicedData) + { + SlicedDataUtil::setMember(ex, slicedData); + } + + Py_INCREF(ex); + return ex; + } + else + { + PyException pye(ex); // No traceback information available. + pye.raise(); + } + } + + throw Ice::UnknownUserException(__FILE__, __LINE__, "unknown exception"); +#ifdef __SUNPRO_CC + return 0; +#endif +} + +bool +IcePy::TypedInvocation::validateException(PyObject* ex) const +{ + for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p) + { + if(PyObject_IsInstance(ex, (*p)->pythonType.get())) + { + return true; + } + } + + return false; +} + +void +IcePy::TypedInvocation::checkTwowayOnly(const Ice::ObjectPrx& proxy) const +{ + if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway()) + { + Ice::TwowayOnlyException ex(__FILE__, __LINE__); + ex.operation = _op->name; + throw ex; + } +} + +// +// SyncTypedInvocation +// +IcePy::SyncTypedInvocation::SyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) : + Invocation(prx), TypedInvocation(prx, op) +{ +} + +PyObject* +IcePy::SyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) +{ + assert(PyTuple_Check(args)); + assert(PyTuple_GET_SIZE(args) == 2); // Format is ((params...), context|None) + PyObject* pyparams = PyTuple_GET_ITEM(args, 0); + assert(PyTuple_Check(pyparams)); + PyObject* pyctx = PyTuple_GET_ITEM(args, 1); + + // + // Marshal the input parameters to a byte sequence. + // + Ice::OutputStreamPtr os; + pair<const Ice::Byte*, const Ice::Byte*> params; + if(!prepareRequest(pyparams, SyncMapping, os, params)) + { + return 0; + } + + try + { + checkTwowayOnly(_prx); + + // + // Invoke the operation. + // + vector<Ice::Byte> result; + bool status; + { + if(pyctx != Py_None) + { + Ice::Context ctx; + + if(!PyDict_Check(pyctx)) + { + PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary")); + return 0; + } + + if(!dictionaryToContext(pyctx, ctx)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + status = _prx->ice_invoke(_op->name, _op->sendMode, params, result, ctx); + } + else + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + status = _prx->ice_invoke(_op->name, _op->sendMode, params, result); + } + } + + // + // Process the reply. + // + if(_prx->ice_isTwoway()) + { + if(!status) + { + // + // Unmarshal a user exception. + // + pair<const Ice::Byte*, const Ice::Byte*> rb(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(!result.empty()) + { + rb.first = &result[0]; + rb.second = &result[0] + result.size(); + } + PyObjectHandle ex = unmarshalException(rb); + + // + // Set the Python exception. + // + setPythonException(ex.get()); + return 0; + } + else if(_op->outParams.size() > 0 || _op->returnType) + { + // + // Unmarshal the results. If there is more than one value to be returned, then return them + // in a tuple of the form (result, outParam1, ...). Otherwise just return the value. + // + pair<const Ice::Byte*, const Ice::Byte*> rb(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(!result.empty()) + { + rb.first = &result[0]; + rb.second = &result[0] + result.size(); + } + PyObjectHandle results = unmarshalResults(rb); + if(!results.get()) + { + return 0; + } + + if(PyTuple_GET_SIZE(results.get()) > 1) + { + return results.release(); + } + else + { + PyObject* ret = PyTuple_GET_ITEM(results.get(), 0); + if(!ret) + { + return 0; + } + else + { + Py_INCREF(ret); + return ret; + } + } + } + } + } + catch(const AbortMarshaling&) + { + assert(PyErr_Occurred()); + return 0; + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +// +// AsyncTypedInvocation +// +IcePy::AsyncTypedInvocation::AsyncTypedInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy, + const OperationPtr& op) : + Invocation(prx), TypedInvocation(prx, op), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0) +{ + Py_INCREF(_pyProxy); +} + +IcePy::AsyncTypedInvocation::~AsyncTypedInvocation() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_pyProxy); + Py_XDECREF(_response); + Py_XDECREF(_ex); + Py_XDECREF(_sent); +} + +PyObject* +IcePy::AsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) +{ + assert(PyTuple_Check(args)); + assert(PyTuple_GET_SIZE(args) == 5); // Format is ((params...), response|None, exception|None, sent|None, ctx|None) + PyObject* pyparams = PyTuple_GET_ITEM(args, 0); + assert(PyTuple_Check(pyparams)); + + PyObject* callable; + + callable = PyTuple_GET_ITEM(args, 1); + if(PyCallable_Check(callable)) + { + _response = callable; + Py_INCREF(_response); + } + else if(callable != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("response callback must be a callable object or None")); + return 0; + } + + callable = PyTuple_GET_ITEM(args, 2); + if(PyCallable_Check(callable)) + { + _ex = callable; + Py_INCREF(_ex); + } + else if(callable != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("exception callback must be a callable object or None")); + return 0; + } + + callable = PyTuple_GET_ITEM(args, 3); + if(PyCallable_Check(callable)) + { + _sent = callable; + Py_INCREF(_sent); + } + else if(callable != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("sent callback must be a callable object or None")); + return 0; + } + + if(!_ex && (_response || _sent)) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("exception callback must also be provided when response or sent callbacks are used")); + return 0; + } + + PyObject* pyctx = PyTuple_GET_ITEM(args, 4); + if(pyctx != Py_None && !PyDict_Check(pyctx)) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("context must be a dictionary or None")); + return 0; + } + + // + // Marshal the input parameters to a byte sequence. + // + Ice::OutputStreamPtr os; + pair<const Ice::Byte*, const Ice::Byte*> params; + if(!prepareRequest(pyparams, AsyncMapping, os, params)) + { + return 0; + } + + Ice::AsyncResultPtr result; + try + { + checkAsyncTwowayOnly(_prx); + + Ice::Callback_Object_ice_invokePtr cb; + if(_response || _ex || _sent) + { + cb = Ice::newCallback_Object_ice_invoke(this, &AsyncTypedInvocation::response, + &AsyncTypedInvocation::exception, &AsyncTypedInvocation::sent); + } + + // + // Invoke the operation asynchronously. + // + if(pyctx != Py_None) + { + Ice::Context ctx; + if(!dictionaryToContext(pyctx, ctx)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + if(cb) + { + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb); + } + else + { + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx); + } + } + else + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + if(cb) + { + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb); + } + else + { + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params); + } + } + } + catch(const Ice::CommunicatorDestroyedException& ex) + { + // + // CommunicatorDestroyedException can propagate directly. + // + setPythonException(ex); + return 0; + } + catch(const IceUtil::IllegalArgumentException& ex) + { + // + // IllegalArgumentException can propagate directly. + // (Raised by checkAsyncTwowayOnly) + // + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + return 0; + } + catch(const Ice::Exception&) + { + // + // No other exceptions should be raised by begin_ice_invoke. + // + assert(false); + } + + assert(result); + AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0); + if(!obj) + { + return 0; + } + obj->result = new Ice::AsyncResultPtr(result); + obj->invocation = new InvocationPtr(this); + obj->proxy = _pyProxy; + Py_INCREF(obj->proxy); + obj->communicator = getCommunicatorWrapper(_communicator); + return reinterpret_cast<PyObject*>(obj); +} + +PyObject* +IcePy::AsyncTypedInvocation::end(const Ice::ObjectPrx& proxy, const OperationPtr& op, const Ice::AsyncResultPtr& r) +{ + try + { + if(op.get() != _op.get()) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "end_" + op->name + + " called with AsyncResult object from begin_" + _op->name); + } + + pair<const Ice::Byte*, const Ice::Byte*> results; + bool ok; + + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking operations. + ok = proxy->___end_ice_invoke(results, r); + } + + if(ok) + { + // + // Unmarshal the results. + // + PyObjectHandle args = unmarshalResults(results); + if(args.get()) + { + // + // If there are no results, return None. If there's only one element + // in the tuple, return the element. Otherwise, return the tuple. + // + assert(PyTuple_Check(args.get())); + if(PyTuple_GET_SIZE(args.get()) == 0) + { + Py_INCREF(Py_None); + return Py_None; + } + else if(PyTuple_GET_SIZE(args.get()) == 1) + { + PyObject* res = PyTuple_GET_ITEM(args.get(), 0); + Py_INCREF(res); + return res; + } + else + { + return args.release(); + } + } + } + else + { + PyObjectHandle ex = unmarshalException(results); + setPythonException(ex.get()); + } + } + catch(const AbortMarshaling&) + { + // Nothing to do. + } + catch(const IceUtil::IllegalArgumentException& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + } + + assert(PyErr_Occurred()); + return 0; +} + +string +IcePy::AsyncTypedInvocation::opName() const +{ + return _op->name; +} + +void +IcePy::AsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + try + { + if(ok) + { + if(_response) + { + // + // Unmarshal the results. + // + PyObjectHandle args; + try + { + args = unmarshalResults(results); + if(!args.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + } + catch(const Ice::Exception& ex) + { + assert(_ex); + callException(_ex, ex); + return; + } + + PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } + } + } + else + { + assert(_ex); + PyObjectHandle ex = unmarshalException(results); + callException(_ex, ex.get()); + } + } + catch(const AbortMarshaling&) + { + assert(PyErr_Occurred()); + PyErr_Print(); + } +} + +void +IcePy::AsyncTypedInvocation::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + assert(_ex); + callException(_ex, ex); +} + +void +IcePy::AsyncTypedInvocation::sent(bool sentSynchronously) +{ + if(_sent) + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + callSent(_sent, sentSynchronously, true); + } +} + +void +IcePy::AsyncTypedInvocation::checkAsyncTwowayOnly(const Ice::ObjectPrx& proxy) const +{ + if((_op->returnType != 0 || !_op->outParams.empty() || !_op->exceptions.empty()) && !proxy->ice_isTwoway()) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, + "`" + _op->name + "' can only be called with a twoway proxy"); + } + + if((_op->returnType != 0 || !_op->outParams.empty()) && (!_response && (_ex || _sent))) + { + throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "`" + _op->name + "' requires a response callback"); + } +} + +// +// OldAsyncTypedInvocation +// +IcePy::OldAsyncTypedInvocation::OldAsyncTypedInvocation(const Ice::ObjectPrx& prx, const OperationPtr& op) + : Invocation(prx), TypedInvocation(prx, op), _callback(0) +{ +} + +IcePy::OldAsyncTypedInvocation::~OldAsyncTypedInvocation() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_XDECREF(_callback); +} + +PyObject* +IcePy::OldAsyncTypedInvocation::invoke(PyObject* args, PyObject* /* kwds */) +{ + assert(PyTuple_Check(args)); + assert(PyTuple_GET_SIZE(args) == 3); // Format is (callback, (params...), context|None) + _callback = PyTuple_GET_ITEM(args, 0); + Py_INCREF(_callback); + PyObject* pyparams = PyTuple_GET_ITEM(args, 1); + assert(PyTuple_Check(pyparams)); + PyObject* pyctx = PyTuple_GET_ITEM(args, 2); + + // + // Marshal the input parameters to a byte sequence. + // + Ice::OutputStreamPtr os; + pair<const Ice::Byte*, const Ice::Byte*> params; + if(!prepareRequest(pyparams, OldAsyncMapping, os, params)) + { + return 0; + } + + bool sentSynchronously = false; + try + { + checkTwowayOnly(_prx); + + Ice::Callback_Object_ice_invokePtr cb = + Ice::newCallback_Object_ice_invoke(this, &OldAsyncTypedInvocation::response, + &OldAsyncTypedInvocation::exception, &OldAsyncTypedInvocation::sent); + + Ice::AsyncResultPtr result; + + // + // Invoke the operation asynchronously. + // + if(pyctx != Py_None) + { + Ice::Context ctx; + + if(!PyDict_Check(pyctx)) + { + PyErr_Format(PyExc_ValueError, STRCAST("context argument must be None or a dictionary")); + return 0; + } + + if(!dictionaryToContext(pyctx, ctx)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, ctx, cb); + } + else + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + result = _prx->begin_ice_invoke(_op->name, _op->sendMode, params, cb); + } + + sentSynchronously = result->sentSynchronously(); + } + catch(const Ice::CommunicatorDestroyedException& ex) + { + // + // CommunicatorDestroyedException can propagate directly. + // + setPythonException(ex); + return 0; + } + catch(const Ice::TwowayOnlyException& ex) + { + // + // Raised by checkTwowayOnly. + // + callException(_callback, _op->name, "ice_exception", ex); + } + catch(const Ice::Exception&) + { + // + // No other exceptions should be raised by begin_ice_invoke. + // + assert(false); + } + + PyRETURN_BOOL(sentSynchronously); +} + +void +IcePy::OldAsyncTypedInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + assert(_callback); + + try + { + if(ok) + { + // + // Unmarshal the results. + // + PyObjectHandle args; + try + { + args = unmarshalResults(results); + if(!args.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + } + catch(const Ice::Exception& ex) + { + callException(_callback, _op->name, "ice_exception", ex); + return; + } + + const string methodName = "ice_response"; + if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str()))) + { + ostringstream ostr; + ostr << "AMI callback object for operation `" << _op->name << "' does not define " << methodName + << "()"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } + else + { + PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str())); + assert(method.get()); + PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } + } + } + else + { + PyObjectHandle ex = unmarshalException(results); + callException(_callback, _op->name, "ice_exception", ex.get()); + } + } + catch(const AbortMarshaling&) + { + assert(PyErr_Occurred()); + PyErr_Print(); + } +} + +void +IcePy::OldAsyncTypedInvocation::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callException(_callback, _op->name, "ice_exception", ex); +} + +void +IcePy::OldAsyncTypedInvocation::sent(bool) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callSent(_callback, "ice_sent", false, false); +} + +// +// SyncBlobjectInvocation +// +IcePy::SyncBlobjectInvocation::SyncBlobjectInvocation(const Ice::ObjectPrx& prx) + : Invocation(prx) +{ +} + +PyObject* +IcePy::SyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) +{ + char* operation; + PyObject* mode; + PyObject* inParams; + PyObject* operationModeType = lookupType("Ice.OperationMode"); + PyObject* ctx = 0; +#if PY_VERSION_HEX >= 0x03000000 + if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode, &PyBytes_Type, &inParams, + &ctx)) + { + return 0; + } +#else + if(!PyArg_ParseTuple(args, STRCAST("sO!O!|O"), &operation, operationModeType, &mode, &PyBuffer_Type, &inParams, + &ctx)) + { + return 0; + } +#endif + + PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value")); + Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get())); + assert(!PyErr_Occurred()); + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = PyBytes_GET_SIZE(inParams); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams)); + in.second = in.first + sz; + } +#else + // + // Use the array API to avoid copying the data. + // + char* charBuf = 0; + Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf); + const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = mem; + in.second = mem + sz; + } +#endif + + try + { + vector<Ice::Byte> out; + + bool ok; + if(ctx == 0 || ctx == Py_None) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + ok = _prx->ice_invoke(operation, sendMode, in, out); + } + else + { + Ice::Context context; + if(!dictionaryToContext(ctx, context)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + ok = _prx->ice_invoke(operation, sendMode, in, out, context); + } + + // + // Prepare the result as a tuple of the bool and out param buffer. + // + PyObjectHandle result = PyTuple_New(2); + if(!result.get()) + { + throwPythonException(); + } + + if(PyTuple_SET_ITEM(result.get(), 0, ok ? getTrue() : getFalse()) < 0) + { + throwPythonException(); + } + +#if PY_VERSION_HEX >= 0x03000000 + PyObjectHandle op; + if(out.empty()) + { + op = PyBytes_FromString(""); + } + else + { + op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(&out[0]), out.size()); + } + if(!op.get()) + { + throwPythonException(); + } +#else + // + // Create the output buffer and copy in the outParams. + // + PyObjectHandle op = PyBuffer_New(out.size()); + if(!op.get()) + { + throwPythonException(); + } + if(!out.empty()) + { + void* buf; + Py_ssize_t sz; + if(PyObject_AsWriteBuffer(op.get(), &buf, &sz)) + { + throwPythonException(); + } + memcpy(buf, &out[0], sz); + } +#endif + + if(PyTuple_SET_ITEM(result.get(), 1, op.get()) < 0) + { + throwPythonException(); + } + op.release(); // PyTuple_SET_ITEM steals a reference. + + return result.release(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +// +// AsyncBlobjectInvocation +// +IcePy::AsyncBlobjectInvocation::AsyncBlobjectInvocation(const Ice::ObjectPrx& prx, PyObject* pyProxy) : + Invocation(prx), _pyProxy(pyProxy), _response(0), _ex(0), _sent(0) +{ + Py_INCREF(_pyProxy); +} + +IcePy::AsyncBlobjectInvocation::~AsyncBlobjectInvocation() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_pyProxy); + Py_XDECREF(_response); + Py_XDECREF(_ex); + Py_XDECREF(_sent); +} + +PyObject* +IcePy::AsyncBlobjectInvocation::invoke(PyObject* args, PyObject* kwds) +{ + static char* argNames[] = + { + const_cast<char*>("op"), + const_cast<char*>("mode"), + const_cast<char*>("inParams"), + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + const_cast<char*>("_ctx"), + 0 + }; + char* operation; + PyObject* mode; + PyObject* inParams; + PyObject* operationModeType = lookupType("Ice.OperationMode"); + PyObject* response = Py_None; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + PyObject* pyctx = Py_None; +#if PY_VERSION_HEX >= 0x03000000 + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("sO!O!|OOOO"), argNames, &operation, operationModeType, &mode, + &PyBytes_Type, &inParams, &response, &ex, &sent, &pyctx)) + { + return 0; + } +#else + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("sO!O!|OOOO"), argNames, &operation, operationModeType, &mode, + &PyBuffer_Type, &inParams, &response, &ex, &sent, &pyctx)) + { + return 0; + } +#endif + + _op = operation; + + PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value")); + Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get())); + assert(!PyErr_Occurred()); + + if(PyCallable_Check(response)) + { + _response = response; + Py_INCREF(_response); + } + else if(response != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("response callback must be a callable object or None")); + return 0; + } + + if(PyCallable_Check(ex)) + { + _ex = ex; + Py_INCREF(_ex); + } + else if(ex != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("exception callback must be a callable object or None")); + return 0; + } + + if(PyCallable_Check(sent)) + { + _sent = sent; + Py_INCREF(_sent); + } + else if(sent != Py_None) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("sent callback must be a callable object or None")); + return 0; + } + + if(!_ex && (_response || _sent)) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("exception callback must also be provided when response or sent callbacks are used")); + return 0; + } + + if(pyctx != Py_None && !PyDict_Check(pyctx)) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("context must be a dictionary or None")); + return 0; + } + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = PyBytes_GET_SIZE(inParams); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams)); + in.second = in.first + sz; + } +#else + // + // Use the array API to avoid copying the data. + // + char* charBuf = 0; + Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf); + const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = mem; + in.second = mem + sz; + } +#endif + + Ice::AsyncResultPtr result; + try + { + Ice::Callback_Object_ice_invokePtr cb; + if(_response || _ex || _sent) + { + cb = Ice::newCallback_Object_ice_invoke(this, &AsyncBlobjectInvocation::response, + &AsyncBlobjectInvocation::exception, + &AsyncBlobjectInvocation::sent); + } + + if(pyctx == Py_None) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + if(cb) + { + result = _prx->begin_ice_invoke(operation, sendMode, in, cb); + } + else + { + result = _prx->begin_ice_invoke(operation, sendMode, in); + } + } + else + { + Ice::Context context; + if(!dictionaryToContext(pyctx, context)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + if(cb) + { + result = _prx->begin_ice_invoke(operation, sendMode, in, context, cb); + } + else + { + result = _prx->begin_ice_invoke(operation, sendMode, in, context); + } + } + } + catch(const Ice::CommunicatorDestroyedException& ex) + { + // + // CommunicatorDestroyedException is the only exception that can propagate directly. + // + setPythonException(ex); + return 0; + } + catch(const Ice::Exception&) + { + // + // No other exceptions should be raised by begin_ice_invoke. + // + assert(false); + } + + assert(result); + AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0); + if(!obj) + { + return 0; + } + obj->result = new Ice::AsyncResultPtr(result); + obj->invocation = new InvocationPtr(this); + obj->proxy = _pyProxy; + Py_INCREF(obj->proxy); + obj->communicator = getCommunicatorWrapper(_prx->ice_getCommunicator()); + return reinterpret_cast<PyObject*>(obj); +} + +PyObject* +IcePy::AsyncBlobjectInvocation::end(const Ice::ObjectPrx& proxy, const Ice::AsyncResultPtr& r) +{ + try + { + pair<const Ice::Byte*, const Ice::Byte*> results; + bool ok; + + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking operations. + ok = proxy->___end_ice_invoke(results, r); + } + + // + // Prepare the results as a tuple of the bool and out param buffer. + // + PyObjectHandle args = PyTuple_New(2); + if(!args.get()) + { + return 0; + } + + if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0) + { + return 0; + } + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = results.second - results.first; + PyObjectHandle op; + if(sz == 0) + { + op = PyBytes_FromString(""); + } + else + { + op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz); + } + if(!op.get()) + { + return 0; + } +#else + // + // Create the output buffer and copy in the outParams. + // + PyObjectHandle op = PyBuffer_New(results.second - results.first); + if(!op.get()) + { + return 0; + } + + void* buf; + Py_ssize_t sz; + if(PyObject_AsWriteBuffer(op.get(), &buf, &sz)) + { + return 0; + } + assert(sz == results.second - results.first); + memcpy(buf, results.first, sz); +#endif + + if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0) + { + return 0; + } + op.release(); // PyTuple_SET_ITEM steals a reference. + + return args.release(); + } + catch(const AbortMarshaling&) + { + // Nothing to do. + } + catch(const IceUtil::IllegalArgumentException& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + } + + assert(PyErr_Occurred()); + return 0; +} + +void +IcePy::AsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results) +{ + if(_response) + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + // + // Prepare the args as a tuple of the bool and out param buffer. + // + PyObjectHandle args = PyTuple_New(2); + if(!args.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + + if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = results.second - results.first; + PyObjectHandle op; + if(sz == 0) + { + op = PyBytes_FromString(""); + } + else + { + op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz); + } + if(!op.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } +#else + // + // Create the output buffer and copy in the outParams. + // + PyObjectHandle op = PyBuffer_New(results.second - results.first); + if(!op.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + + void* buf; + Py_ssize_t sz; + if(PyObject_AsWriteBuffer(op.get(), &buf, &sz)) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + assert(sz == results.second - results.first); + memcpy(buf, results.first, sz); +#endif + + if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + op.release(); // PyTuple_SET_ITEM steals a reference. + + PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } + } +} + +void +IcePy::AsyncBlobjectInvocation::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + assert(_ex); + callException(_ex, ex); +} + +void +IcePy::AsyncBlobjectInvocation::sent(bool sentSynchronously) +{ + if(_sent) + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + callSent(_sent, sentSynchronously, true); + } +} + +// +// OldAsyncBlobjectInvocation +// +IcePy::OldAsyncBlobjectInvocation::OldAsyncBlobjectInvocation(const Ice::ObjectPrx& prx) : + Invocation(prx), _callback(0) +{ +} + +IcePy::OldAsyncBlobjectInvocation::~OldAsyncBlobjectInvocation() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_XDECREF(_callback); +} + +PyObject* +IcePy::OldAsyncBlobjectInvocation::invoke(PyObject* args, PyObject* /* kwds */) +{ + char* operation; + PyObject* mode; + PyObject* inParams; + PyObject* operationModeType = lookupType("Ice.OperationMode"); + PyObject* ctx = 0; +#if PY_VERSION_HEX >= 0x03000000 + if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode, + &PyBytes_Type, &inParams, &ctx)) + { + return 0; + } +#else + if(!PyArg_ParseTuple(args, STRCAST("OsO!O!|O"), &_callback, &operation, operationModeType, &mode, + &PyBuffer_Type, &inParams, &ctx)) + { + return 0; + } +#endif + + Py_INCREF(_callback); + _op = operation; + + PyObjectHandle modeValue = PyObject_GetAttrString(mode, STRCAST("value")); + Ice::OperationMode sendMode = (Ice::OperationMode)static_cast<int>(PyLong_AsLong(modeValue.get())); + assert(!PyErr_Occurred()); + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = PyBytes_GET_SIZE(inParams); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(inParams)); + in.second = in.first + sz; + } +#else + // + // Use the array API to avoid copying the data. + // + char* charBuf = 0; + Py_ssize_t sz = inParams->ob_type->tp_as_buffer->bf_getcharbuffer(inParams, 0, &charBuf); + const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf); + pair<const ::Ice::Byte*, const ::Ice::Byte*> in(static_cast<const Ice::Byte*>(0), + static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + in.first = mem; + in.second = mem + sz; + } +#endif + + bool sentSynchronously = false; + try + { + Ice::AsyncResultPtr result; + Ice::Callback_Object_ice_invokePtr cb = + Ice::newCallback_Object_ice_invoke(this, &OldAsyncBlobjectInvocation::response, + &OldAsyncBlobjectInvocation::exception, + &OldAsyncBlobjectInvocation::sent); + + if(ctx == 0 || ctx == Py_None) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + result = _prx->begin_ice_invoke(operation, sendMode, in, cb); + } + else + { + Ice::Context context; + if(!dictionaryToContext(ctx, context)) + { + return 0; + } + + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + result = _prx->begin_ice_invoke(operation, sendMode, in, context, cb); + } + + sentSynchronously = result->sentSynchronously(); + } + catch(const Ice::CommunicatorDestroyedException& ex) + { + // + // CommunicatorDestroyedException is the only exception that can propagate directly. + // + setPythonException(ex); + return 0; + } + catch(const Ice::Exception&) + { + // + // No other exceptions should be raised by begin_ice_invoke. + // + assert(false); + } + + PyRETURN_BOOL(sentSynchronously); +} + +void +IcePy::OldAsyncBlobjectInvocation::response(bool ok, const pair<const Ice::Byte*, const Ice::Byte*>& results) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + try + { + // + // Prepare the args as a tuple of the bool and out param buffer. + // + PyObjectHandle args = PyTuple_New(2); + if(!args.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + + if(PyTuple_SET_ITEM(args.get(), 0, ok ? getTrue() : getFalse()) < 0) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + +#if PY_VERSION_HEX >= 0x03000000 + Py_ssize_t sz = results.second - results.first; + PyObjectHandle op; + if(sz == 0) + { + op = PyBytes_FromString(""); + } + else + { + op = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(results.first), sz); + } + if(!op.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } +#else + // + // Create the output buffer and copy in the outParams. + // + PyObjectHandle op = PyBuffer_New(results.second - results.first); + if(!op.get()) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + + void* buf; + Py_ssize_t sz; + if(PyObject_AsWriteBuffer(op.get(), &buf, &sz)) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + assert(sz == results.second - results.first); + memcpy(buf, results.first, sz); +#endif + + if(PyTuple_SET_ITEM(args.get(), 1, op.get()) < 0) + { + assert(PyErr_Occurred()); + PyErr_Print(); + return; + } + op.release(); // PyTuple_SET_ITEM steals a reference. + + const string methodName = "ice_response"; + if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str()))) + { + ostringstream ostr; + ostr << "AMI callback object for operation `ice_invoke_async' does not define " << methodName << "()"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } + else + { + PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str())); + assert(method.get()); + PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } + } + } + catch(const Ice::Exception& ex) + { + ostringstream ostr; + ostr << "Exception raised by AMI callback for operation `ice_invoke_async':" << ex; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } +} + +void +IcePy::OldAsyncBlobjectInvocation::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callException(_callback, "ice_invoke", "ice_exception", ex); +} + +void +IcePy::OldAsyncBlobjectInvocation::sent(bool) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callSent(_callback, "ice_sent", false, false); +} + +// +// TypedUpcall +// +IcePy::TypedUpcall::TypedUpcall(const OperationPtr& op, const Ice::AMD_Object_ice_invokePtr& callback, + const Ice::CommunicatorPtr& communicator) : + _op(op), _callback(callback), _communicator(communicator), _finished(false) +{ +} + +void +IcePy::TypedUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, const Ice::Byte*>& inBytes, + const Ice::Current& current) +{ + // + // Unmarshal the in parameters. We have to leave room in the arguments for a trailing + // Ice::Current object. + // + Py_ssize_t count = static_cast<Py_ssize_t>(_op->inParams.size()) + 1; + + Py_ssize_t offset = 0; + if(_op->amd) + { + ++count; // Leave room for a leading AMD callback argument. + offset = 1; + } + + PyObjectHandle args = PyTuple_New(count); + if(!args.get()) + { + throwPythonException(); + } + + if(!_op->inParams.empty()) + { + Ice::InputStreamPtr is = Ice::wrapInputStream(_communicator, inBytes); + + // + // Store a pointer to a local SlicedDataUtil object as the stream's closure. + // This is necessary to support object unmarshaling (see ObjectReader). + // + SlicedDataUtil util; + assert(!is->closure()); + is->closure(&util); + + try + { + is->startEncapsulation(); + + ParamInfoList::iterator p; + + // + // Unmarshal the required parameters. + // + for(p = _op->inParams.begin(); p != _op->inParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(!info->optional) + { + void* closure = reinterpret_cast<void*>(info->pos + offset); + info->type->unmarshal(is, info, args.get(), closure, false, &info->metaData); + } + } + + // + // Unmarshal the optional parameters. + // + for(p = _op->optionalInParams.begin(); p != _op->optionalInParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(is->readOptional(info->tag, info->type->optionalFormat())) + { + void* closure = reinterpret_cast<void*>(info->pos + offset); + info->type->unmarshal(is, info, args.get(), closure, true, &info->metaData); + } + else + { + if(PyTuple_SET_ITEM(args.get(), info->pos + offset, Unset) < 0) + { + throwPythonException(); + } + Py_INCREF(Unset); // PyTuple_SET_ITEM steals a reference. + } + } + + if(_op->sendsClasses) + { + is->readPendingObjects(); + } + + is->endEncapsulation(); + + util.update(); + } + catch(const AbortMarshaling&) + { + throwPythonException(); + } + } + + // + // Create an object to represent Ice::Current. We need to append this to the argument tuple. + // + PyObjectHandle curr = createCurrent(current); + if(PyTuple_SET_ITEM(args.get(), PyTuple_GET_SIZE(args.get()) - 1, curr.get()) < 0) + { + throwPythonException(); + } + curr.release(); // PyTuple_SET_ITEM steals a reference. + + if(_op->amd) + { + // + // Create the callback object and pass it as the first argument. + // + AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0); + if(!obj) + { + throwPythonException(); + } + obj->upcall = new UpcallPtr(this); + obj->encoding = current.encoding; + if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference. + { + Py_DECREF(obj); + throwPythonException(); + } + } + + // + // Dispatch the operation. Use _dispatchName here, not current.operation. + // + PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(_op->dispatchName.c_str())); + if(!method.get()) + { + ostringstream ostr; + ostr << "servant for identity " << _communicator->identityToString(current.id) + << " does not define operation `" << _op->dispatchName << "'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + Ice::UnknownException ex(__FILE__, __LINE__); + ex.unknown = str; + throw ex; + } + + PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0); + + // + // Check for exceptions. + // + if(PyErr_Occurred()) + { + PyException ex; // Retrieve it before another Python API call clears it. + exception(ex, current.encoding); + return; + } + + if(!_op->amd) + { + response(result.get(), current.encoding); + } +} + +void +IcePy::TypedUpcall::response(PyObject* args, const Ice::EncodingVersion& encoding) +{ + if(_finished) + { + // + // This method could be called more than once if the application calls + // ice_response multiple times. We ignore subsequent calls. + // + return; + } + + _finished = true; + + try + { + // + // Marshal the results. If there is more than one value to be returned, then they must be + // returned in a tuple of the form (result, outParam1, ...). + // + Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator); + try + { + Py_ssize_t numResults = static_cast<Py_ssize_t>(_op->outParams.size()); + if(_op->returnType) + { + numResults++; + } + + if(numResults > 1 && (!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != numResults)) + { + ostringstream ostr; + ostr << "operation `" << fixIdent(_op->name) << "' should return a tuple of length " << numResults; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + + // + // Normalize the args value. For an AMD operation, or when there are multiple + // result values, args is already a tuple. Otherwise, we create a tuple to + // make the code a little simpler. + // + PyObjectHandle t; + if(_op->amd || numResults > 1) + { + t = args; + } + else + { + t = PyTuple_New(1); + if(!t.get()) + { + throw AbortMarshaling(); + } + PyTuple_SET_ITEM(t.get(), 0, args); + } + Py_INCREF(args); + + os->startEncapsulation(encoding, _op->format); + + ObjectMap objectMap; + ParamInfoList::iterator p; + + // + // Validate the results. + // + for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p) + { + ParamInfoPtr info = *p; + PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos); + if((!info->optional || arg != Unset) && !info->type->validate(arg)) + { + // TODO: Provide the parameter name instead? + ostringstream ostr; + ostr << "invalid value for out argument " << (info->pos + 1) << " in operation `" + << _op->dispatchName << "'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + } + if(_op->returnType) + { + PyObject* res = PyTuple_GET_ITEM(t.get(), 0); + if((!_op->returnType->optional || res != Unset) && !_op->returnType->type->validate(res)) + { + ostringstream ostr; + ostr << "invalid return value for operation `" << _op->dispatchName << "'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + } + + // + // Marshal the required out parameters. + // + for(p = _op->outParams.begin(); p != _op->outParams.end(); ++p) + { + ParamInfoPtr info = *p; + if(!info->optional) + { + PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos); + info->type->marshal(arg, os, &objectMap, false, &info->metaData); + } + } + + // + // Marshal the required return value, if any. + // + if(_op->returnType && !_op->returnType->optional) + { + PyObject* res = PyTuple_GET_ITEM(t.get(), 0); + _op->returnType->type->marshal(res, os, &objectMap, false, &_op->metaData); + } + + // + // Marshal the optional results. + // + for(p = _op->optionalOutParams.begin(); p != _op->optionalOutParams.end(); ++p) + { + ParamInfoPtr info = *p; + PyObject* arg = PyTuple_GET_ITEM(t.get(), info->pos); + if(arg != Unset && os->writeOptional(info->tag, info->type->optionalFormat())) + { + info->type->marshal(arg, os, &objectMap, true, &info->metaData); + } + } + + if(_op->returnsClasses) + { + os->writePendingObjects(); + } + + os->endEncapsulation(); + + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_response(true, os->finished()); + } + catch(const AbortMarshaling&) + { + throwPythonException(); + } + } + catch(const Ice::Exception& ex) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_exception(ex); + } +} + +void +IcePy::TypedUpcall::exception(PyException& ex, const Ice::EncodingVersion& encoding) +{ + if(_finished) + { + // + // An asynchronous response or exception has already been sent. We just + // raise an exception and let the C++ run time handle it. + // + ex.raise(); + } + + _finished = true; + + try + { + try + { + // + // A servant that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + PyObject* userExceptionType = lookupType("Ice.UserException"); + + if(PyObject_IsInstance(ex.ex.get(), userExceptionType)) + { + // + // Get the exception's type and verify that it is legal to be thrown from this operation. + // + PyObjectHandle iceType = PyObject_GetAttrString(ex.ex.get(), STRCAST("_ice_type")); + assert(iceType.get()); + ExceptionInfoPtr info = ExceptionInfoPtr::dynamicCast(getException(iceType.get())); + assert(info); + if(!validateException(ex.ex.get())) + { + ex.raise(); // Raises UnknownUserException. + } + else + { + Ice::OutputStreamPtr os = Ice::createOutputStream(_communicator); + os->startEncapsulation(encoding, _op->format); + + ExceptionWriter writer(_communicator, ex.ex, info); + os->writeException(writer); + + os->endEncapsulation(); + + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_response(false, os->finished()); + } + } + else + { + ex.raise(); + } + } + catch(const AbortMarshaling&) + { + throwPythonException(); + } + } + catch(const Ice::Exception& ex) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_exception(ex); + } +} + +bool +IcePy::TypedUpcall::validateException(PyObject* ex) const +{ + for(ExceptionInfoList::const_iterator p = _op->exceptions.begin(); p != _op->exceptions.end(); ++p) + { + if(PyObject_IsInstance(ex, (*p)->pythonType.get())) + { + return true; + } + } + + return false; +} + +// +// BlobjectUpcall +// +IcePy::BlobjectUpcall::BlobjectUpcall(bool amd, const Ice::AMD_Object_ice_invokePtr& callback) : + _amd(amd), _callback(callback), _finished(false) +{ +} + +void +IcePy::BlobjectUpcall::dispatch(PyObject* servant, const pair<const Ice::Byte*, const Ice::Byte*>& inBytes, + const Ice::Current& current) +{ + Ice::CommunicatorPtr communicator = current.adapter->getCommunicator(); + + Py_ssize_t count = 2; // First is the inParams, second is the Ice::Current object. + + Py_ssize_t start = 0; + if(_amd) + { + ++count; // Leave room for a leading AMD callback argument. + start = 1; + } + + PyObjectHandle args = PyTuple_New(count); + if(!args.get()) + { + throwPythonException(); + } + + PyObjectHandle ip; + +#if PY_VERSION_HEX >= 0x03000000 + if(inBytes.second == inBytes.first) + { + ip = PyBytes_FromString(""); + } + else + { + ip = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(inBytes.first), inBytes.second - inBytes.first); + } +#else + // + // If using AMD we need to copy the bytes since the bytes may be + // accessed after this method is over, otherwise + // PyBuffer_FromMemory can be used which doesn't do a copy. + // + if(!_amd) + { + ip = PyBuffer_FromMemory((void*)inBytes.first, inBytes.second - inBytes.first); + if(!ip.get()) + { + throwPythonException(); + } + } + else + { + ip = PyBuffer_New(inBytes.second - inBytes.first); + if(!ip.get()) + { + throwPythonException(); + } + void* buf; + Py_ssize_t sz; + if(PyObject_AsWriteBuffer(ip.get(), &buf, &sz)) + { + throwPythonException(); + } + assert(sz == inBytes.second - inBytes.first); + memcpy(buf, inBytes.first, sz); + } +#endif + + if(PyTuple_SET_ITEM(args.get(), start, ip.get()) < 0) + { + throwPythonException(); + } + ++start; + ip.release(); // PyTuple_SET_ITEM steals a reference. + + // + // Create an object to represent Ice::Current. We need to append + // this to the argument tuple. + // + PyObjectHandle curr = createCurrent(current); + if(PyTuple_SET_ITEM(args.get(), start, curr.get()) < 0) + { + throwPythonException(); + } + curr.release(); // PyTuple_SET_ITEM steals a reference. + + string dispatchName = "ice_invoke"; + if(_amd) + { + dispatchName += "_async"; + // + // Create the callback object and pass it as the first argument. + // + AMDCallbackObject* obj = amdCallbackNew(&AMDCallbackType, 0, 0); + if(!obj) + { + throwPythonException(); + } + obj->upcall = new UpcallPtr(this); + obj->encoding = current.encoding; + if(PyTuple_SET_ITEM(args.get(), 0, (PyObject*)obj) < 0) // PyTuple_SET_ITEM steals a reference. + { + Py_DECREF(obj); + throwPythonException(); + } + } + + // + // Dispatch the operation. + // + PyObjectHandle method = PyObject_GetAttrString(servant, const_cast<char*>(dispatchName.c_str())); + if(!method.get()) + { + ostringstream ostr; + ostr << "servant for identity " << communicator->identityToString(current.id) + << " does not define operation `" << dispatchName << "'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + Ice::UnknownException ex(__FILE__, __LINE__); + ex.unknown = str; + throw ex; + } + + PyObjectHandle result = PyObject_Call(method.get(), args.get(), 0); + + // + // Check for exceptions. + // + if(PyErr_Occurred()) + { + PyException ex; // Retrieve it before another Python API call clears it. + exception(ex, current.encoding); + return; + } + + if(!_amd) + { + response(result.get(), current.encoding); + } +} + +void +IcePy::BlobjectUpcall::response(PyObject* args, const Ice::EncodingVersion&) +{ + if(_finished) + { + // + // This method could be called more than once if the application calls + // ice_response multiple times. We ignore subsequent calls. + // + return; + } + + _finished = true; + + // + // The return value is a tuple of (bool, results). + // + if(!PyTuple_Check(args) || PyTuple_GET_SIZE(args) != 2) + { + ostringstream ostr; + string name = "ice_invoke"; + if(_amd) + { + name += "_async"; + } + ostr << "operation `" << name << "' should return a tuple of length 2"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + + PyObject* arg = PyTuple_GET_ITEM(args, 0); + bool isTrue = PyObject_IsTrue(arg) == 1; + + arg = PyTuple_GET_ITEM(args, 1); + +#if PY_VERSION_HEX >= 0x03000000 + if(!PyBytes_Check(arg)) + { + ostringstream ostr; + ostr << "invalid return value for operation `ice_invoke'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + + Py_ssize_t sz = PyBytes_GET_SIZE(arg); + pair<const ::Ice::Byte*, const ::Ice::Byte*> r(static_cast<const Ice::Byte*>(0),static_cast<const Ice::Byte*>(0)); + if(sz > 0) + { + r.first = reinterpret_cast<Ice::Byte*>(PyBytes_AS_STRING(arg)); + r.second = r.first + sz; + } +#else + if(!PyBuffer_Check(arg)) + { + ostringstream ostr; + ostr << "invalid return value for operation `ice_invoke'"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + throw Ice::MarshalException(__FILE__, __LINE__); + } + + char* charBuf = 0; + Py_ssize_t sz = arg->ob_type->tp_as_buffer->bf_getcharbuffer(arg, 0, &charBuf); + const Ice::Byte* mem = reinterpret_cast<const Ice::Byte*>(charBuf); + const pair<const ::Ice::Byte*, const ::Ice::Byte*> r(mem, mem + sz); +#endif + + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_response(isTrue, r); +} + +void +IcePy::BlobjectUpcall::exception(PyException& ex, const Ice::EncodingVersion&) +{ + if(_finished) + { + // + // An asynchronous response or exception has already been sent. We just + // raise an exception and let the C++ run time handle it. + // + ex.raise(); + } + + _finished = true; + + try + { + // + // A servant that calls sys.exit() will raise the SystemExit exception. + // This is normally caught by the interpreter, causing it to exit. + // However, we have no way to pass this exception to the interpreter, + // so we act on it directly. + // + ex.checkSystemExit(); + + ex.raise(); + } + catch(const Ice::Exception& ex) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + _callback->ice_exception(ex); + } +} + +PyObject* +IcePy::invokeBuiltin(PyObject* proxy, const string& builtin, PyObject* args) +{ + string name = "_op_" + builtin; + PyObject* objectType = lookupType("Ice.Object"); + assert(objectType); + PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str())); + assert(obj.get()); + + OperationPtr op = getOperation(obj.get()); + assert(op); + + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new SyncTypedInvocation(p, op); + return i->invoke(args); +} + +PyObject* +IcePy::beginBuiltin(PyObject* proxy, const string& builtin, PyObject* args) +{ + string name = "_op_" + builtin; + PyObject* objectType = lookupType("Ice.Object"); + assert(objectType); + PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str())); + assert(obj.get()); + + OperationPtr op = getOperation(obj.get()); + assert(op); + + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new AsyncTypedInvocation(p, proxy, op); + return i->invoke(args); +} + +PyObject* +IcePy::endBuiltin(PyObject* proxy, const string& builtin, PyObject* args) +{ + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + string name = "_op_" + builtin; + PyObject* objectType = lookupType("Ice.Object"); + assert(objectType); + PyObjectHandle obj = PyObject_GetAttrString(objectType, STRCAST(name.c_str())); + assert(obj.get()); + + OperationPtr op = getOperation(obj.get()); + assert(op); + + AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result); + assert(ar); + AsyncTypedInvocationPtr i = AsyncTypedInvocationPtr::dynamicCast(*ar->invocation); + if(!i) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_%s"), op->name.c_str()); + return 0; + } + Ice::ObjectPrx p = getProxy(proxy); + return i->end(p, op, *ar->result); +} + +PyObject* +IcePy::iceInvoke(PyObject* proxy, PyObject* args) +{ + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new SyncBlobjectInvocation(p); + return i->invoke(args); +} + +PyObject* +IcePy::iceInvokeAsync(PyObject* proxy, PyObject* args) +{ + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new OldAsyncBlobjectInvocation(p); + return i->invoke(args); +} + +PyObject* +IcePy::beginIceInvoke(PyObject* proxy, PyObject* args, PyObject* kwds) +{ + Ice::ObjectPrx p = getProxy(proxy); + InvocationPtr i = new AsyncBlobjectInvocation(p, proxy); + return i->invoke(args, kwds); +} + +PyObject* +IcePy::endIceInvoke(PyObject* proxy, PyObject* args) +{ + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + AsyncResultObject* ar = reinterpret_cast<AsyncResultObject*>(result); + assert(ar); + AsyncBlobjectInvocationPtr i = AsyncBlobjectInvocationPtr::dynamicCast(*ar->invocation); + if(!i) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid AsyncResult object passed to end_ice_invoke")); + return 0; + } + Ice::ObjectPrx p = getProxy(proxy); + return i->end(p, *ar->result); +} + +PyObject* +IcePy::createAsyncResult(const Ice::AsyncResultPtr& r, PyObject* proxy, PyObject* connection, PyObject* communicator) +{ + AsyncResultObject* obj = asyncResultNew(&AsyncResultType, 0, 0); + if(!obj) + { + return 0; + } + obj->result = new Ice::AsyncResultPtr(r); + obj->proxy = proxy; + Py_XINCREF(obj->proxy); + obj->connection = connection; + Py_XINCREF(obj->connection); + obj->communicator = communicator; + Py_XINCREF(obj->communicator); + return reinterpret_cast<PyObject*>(obj); +} + +Ice::AsyncResultPtr +IcePy::getAsyncResult(PyObject* p) +{ + assert(PyObject_IsInstance(p, reinterpret_cast<PyObject*>(&AsyncResultType)) == 1); + AsyncResultObject* obj = reinterpret_cast<AsyncResultObject*>(p); + return *obj->result; +} + +IcePy::FlushCallback::FlushCallback(PyObject* ex, PyObject* sent, const string& op) : + _ex(ex), _sent(sent), _op(op) +{ + assert(_ex); + Py_INCREF(_ex); + Py_XINCREF(_sent); +} + +IcePy::FlushCallback::~FlushCallback() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_ex); + Py_XDECREF(_sent); +} + +void +IcePy::FlushCallback::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callException(_ex, ex); +} + +void +IcePy::FlushCallback::sent(bool sentSynchronously) +{ + if(_sent) + { + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + callSent(_sent, sentSynchronously, true); + } +} + +IcePy::GetConnectionCallback::GetConnectionCallback(const Ice::CommunicatorPtr& communicator, + PyObject* response, PyObject* ex, const string& op) : + _communicator(communicator), _response(response), _ex(ex), _op(op) +{ + assert(_response); + Py_INCREF(_response); + Py_XINCREF(_ex); +} + +IcePy::GetConnectionCallback::~GetConnectionCallback() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_response); + Py_XDECREF(_ex); +} + +void +IcePy::GetConnectionCallback::response(const Ice::ConnectionPtr& conn) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle pyConn = createConnection(conn, _communicator); + PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), pyConn.get()); + PyObjectHandle tmp = PyObject_Call(_response, args.get(), 0); + if(PyErr_Occurred()) + { + handleException(); // Callback raised an exception. + } +} + +void +IcePy::GetConnectionCallback::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + callException(_ex, ex); +} + +// +// ServantWrapper implementation. +// +IcePy::ServantWrapper::ServantWrapper(PyObject* servant) : + _servant(servant) +{ + Py_INCREF(_servant); +} + +IcePy::ServantWrapper::~ServantWrapper() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_servant); +} + +PyObject* +IcePy::ServantWrapper::getObject() +{ + Py_INCREF(_servant); + return _servant; +} + +// +// TypedServantWrapper implementation. +// +IcePy::TypedServantWrapper::TypedServantWrapper(PyObject* servant) : + ServantWrapper(servant), _lastOp(_operationMap.end()) +{ +} + +void +IcePy::TypedServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, + const pair<const Ice::Byte*, const Ice::Byte*>& inParams, + const Ice::Current& current) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + try + { + // + // Locate the Operation object. As an optimization we keep a reference + // to the most recent operation we've dispatched, so check that first. + // + OperationPtr op; + if(_lastOp != _operationMap.end() && _lastOp->first == current.operation) + { + op = _lastOp->second; + } + else + { + // + // Next check our cache of operations. + // + _lastOp = _operationMap.find(current.operation); + if(_lastOp == _operationMap.end()) + { + // + // Look for the Operation object in the servant's type. + // + string attrName = "_op_" + current.operation; + PyObjectHandle h = PyObject_GetAttrString((PyObject*)_servant->ob_type, + const_cast<char*>(attrName.c_str())); + if(!h.get()) + { + PyErr_Clear(); + Ice::OperationNotExistException ex(__FILE__, __LINE__); + ex.id = current.id; + ex.facet = current.facet; + ex.operation = current.operation; + throw ex; + } + + assert(PyObject_IsInstance(h.get(), reinterpret_cast<PyObject*>(&OperationType)) == 1); + OperationObject* obj = reinterpret_cast<OperationObject*>(h.get()); + op = *obj->op; + _lastOp = _operationMap.insert(OperationMap::value_type(current.operation, op)).first; + } + else + { + op = _lastOp->second; + } + } + + // + // See bug 4976. + // + if(!op->pseudoOp) + { + __checkMode(op->mode, current.mode); + } + + UpcallPtr up = new TypedUpcall(op, cb, current.adapter->getCommunicator()); + up->dispatch(_servant, inParams, current); + } + catch(const Ice::Exception& ex) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + cb->ice_exception(ex); + } +} + +// +// BlobjectServantWrapper implementation. +// +IcePy::BlobjectServantWrapper::BlobjectServantWrapper(PyObject* servant, bool amd) : + ServantWrapper(servant), _amd(amd) +{ +} + +void +IcePy::BlobjectServantWrapper::ice_invoke_async(const Ice::AMD_Object_ice_invokePtr& cb, + const pair<const Ice::Byte*, const Ice::Byte*>& inParams, + const Ice::Current& current) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + try + { + UpcallPtr up = new BlobjectUpcall(_amd, cb); + up->dispatch(_servant, inParams, current); + } + catch(const Ice::Exception& ex) + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking calls. + cb->ice_exception(ex); + } +} + +IcePy::ServantWrapperPtr +IcePy::createServantWrapper(PyObject* servant) +{ + ServantWrapperPtr wrapper; + PyObject* blobjectType = lookupType("Ice.Blobject"); + PyObject* blobjectAsyncType = lookupType("Ice.BlobjectAsync"); + if(PyObject_IsInstance(servant, blobjectType)) + { + return new BlobjectServantWrapper(servant, false); + } + else if(PyObject_IsInstance(servant, blobjectAsyncType)) + { + return new BlobjectServantWrapper(servant, true); + } + + return new TypedServantWrapper(servant); +} diff --git a/python/modules/IcePy/Operation.h b/python/modules/IcePy/Operation.h new file mode 100644 index 00000000000..cf10184b9cb --- /dev/null +++ b/python/modules/IcePy/Operation.h @@ -0,0 +1,108 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_OPERATION_H +#define ICEPY_OPERATION_H + +#include <Config.h> +#include <Ice/Current.h> +#include <Ice/Object.h> +#include <Ice/AsyncResultF.h> +#include <Ice/CommunicatorF.h> + +namespace IcePy +{ + +bool initOperation(PyObject*); + +// +// Builtin operations. +// +PyObject* invokeBuiltin(PyObject*, const std::string&, PyObject*); +PyObject* beginBuiltin(PyObject*, const std::string&, PyObject*); +PyObject* endBuiltin(PyObject*, const std::string&, PyObject*); + +// +// Blobject invocations. +// +PyObject* iceInvoke(PyObject*, PyObject*); +PyObject* iceInvokeAsync(PyObject*, PyObject*); +PyObject* beginIceInvoke(PyObject*, PyObject*, PyObject*); +PyObject* endIceInvoke(PyObject*, PyObject*); + +extern PyTypeObject AsyncResultType; +PyObject* createAsyncResult(const Ice::AsyncResultPtr&, PyObject*, PyObject*, PyObject*); +Ice::AsyncResultPtr getAsyncResult(PyObject*); + +// +// Used as the callback for getConnection operation. +// +class GetConnectionCallback : public IceUtil::Shared +{ +public: + + GetConnectionCallback(const Ice::CommunicatorPtr&, PyObject*, PyObject*, const std::string&); + ~GetConnectionCallback(); + + void response(const Ice::ConnectionPtr&); + void exception(const Ice::Exception&); + +protected: + + Ice::CommunicatorPtr _communicator; + PyObject* _response; + PyObject* _ex; + std::string _op; +}; +typedef IceUtil::Handle<GetConnectionCallback> GetConnectionCallbackPtr; + +// +// Used as the callback for the various flushBatchRequest operations. +// +class FlushCallback : public IceUtil::Shared +{ +public: + + FlushCallback(PyObject*, PyObject*, const std::string&); + ~FlushCallback(); + + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + PyObject* _ex; + PyObject* _sent; + std::string _op; +}; +typedef IceUtil::Handle<FlushCallback> FlushCallbackPtr; + +// +// ServantWrapper handles dispatching to a Python servant. +// +class ServantWrapper : public Ice::BlobjectArrayAsync +{ +public: + + ServantWrapper(PyObject*); + ~ServantWrapper(); + + PyObject* getObject(); + +protected: + + PyObject* _servant; +}; +typedef IceUtil::Handle<ServantWrapper> ServantWrapperPtr; + +ServantWrapperPtr createServantWrapper(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/Properties.cpp b/python/modules/IcePy/Properties.cpp new file mode 100644 index 00000000000..d990e2500ec --- /dev/null +++ b/python/modules/IcePy/Properties.cpp @@ -0,0 +1,804 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Properties.h> +#include <Util.h> +#include <Ice/Initialize.h> +#include <Ice/Properties.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct PropertiesObject +{ + PyObject_HEAD + Ice::PropertiesPtr* properties; +}; + +} + +#ifdef WIN32 +extern "C" +#endif +static PropertiesObject* +propertiesNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PropertiesObject* self = reinterpret_cast<PropertiesObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->properties = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static int +propertiesInit(PropertiesObject* self, PyObject* args, PyObject* /*kwds*/) +{ + PyObject* arglist = 0; + PyObject* defaultsObj = 0; + + if(!PyArg_ParseTuple(args, STRCAST("|OO"), &arglist, &defaultsObj)) + { + return -1; + } + + Ice::StringSeq seq; + if(arglist) + { + PyTypeObject* listType = &PyList_Type; // Necessary to prevent GCC's strict-alias warnings. + if(PyObject_IsInstance(arglist, reinterpret_cast<PyObject*>(listType))) + { + if(!listToStringSeq(arglist, seq)) + { + return -1; + } + } + else if(arglist != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("args must be None or a list")); + return -1; + } + } + + Ice::PropertiesPtr defaults; + if(defaultsObj) + { + PyObject* propType = lookupType("Ice.PropertiesI"); + assert(propType); + if(PyObject_IsInstance(defaultsObj, propType)) + { + PyObjectHandle impl = PyObject_GetAttrString(defaultsObj, STRCAST("_impl")); + defaults = getProperties(impl.get()); + } + else if(defaultsObj != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("defaults must be None or a Ice.Properties")); + return -1; + } + } + + Ice::PropertiesPtr props; + try + { + if(defaults || (arglist && arglist != Py_None)) + { + props = Ice::createProperties(seq, defaults); + } + else + { + props = Ice::createProperties(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return -1; + } + + // + // Replace the contents of the given argument list with the filtered arguments. + // + if(arglist && arglist != Py_None) + { + if(PyList_SetSlice(arglist, 0, PyList_Size(arglist), 0) < 0) + { + return -1; + } + if(!stringSeqToList(seq, arglist)) + { + return -1; + } + } + + self->properties = new Ice::PropertiesPtr(props); + + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +propertiesDealloc(PropertiesObject* self) +{ + delete self->properties; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesStr(PropertiesObject* self) +{ + assert(self->properties); + + Ice::PropertyDict dict; + try + { + dict = (*self->properties)->getPropertiesForPrefix(""); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + string str; + for(Ice::PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + if(p != dict.begin()) + { + str.append("\n"); + } + str.append(p->first + "=" + p->second); + } + + return createString(str); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetProperty(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + assert(self->properties); + string value; + try + { + value = (*self->properties)->getProperty(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(value); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertyWithDefault(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + PyObject* defObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &keyObj, &defObj)) + { + return 0; + } + + string key; + string def; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + if(!getStringArg(defObj, "value", def)) + { + return 0; + } + + assert(self->properties); + string value; + try + { + value = (*self->properties)->getPropertyWithDefault(key, def); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(value); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertyAsInt(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + assert(self->properties); + Ice::Int value; + try + { + value = (*self->properties)->getPropertyAsInt(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return PyLong_FromLong(value); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertyAsIntWithDefault(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + int def; + if(!PyArg_ParseTuple(args, STRCAST("Oi"), &keyObj, &def)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + assert(self->properties); + Ice::Int value; + try + { + value = (*self->properties)->getPropertyAsIntWithDefault(key, def); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return PyLong_FromLong(value); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertyAsList(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &keyObj)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + assert(self->properties); + Ice::StringSeq value; + try + { + value = (*self->properties)->getPropertyAsList(key); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* list = PyList_New(0); + if(!list) + { + return 0; + } + if(!stringSeqToList(value, list)) + { + return 0; + } + + return list; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertyAsListWithDefault(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + PyObject* defList; + if(!PyArg_ParseTuple(args, STRCAST("OO!"), &keyObj, &PyList_Type, &defList)) + { + return 0; + } + + string key; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + + assert(self->properties); + Ice::StringSeq def; + if(!listToStringSeq(defList, def)) + { + return 0; + } + + Ice::StringSeq value; + try + { + value = (*self->properties)->getPropertyAsListWithDefault(key, def); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* list = PyList_New(0); + if(!list) + { + return 0; + } + if(!stringSeqToList(value, list)) + { + return 0; + } + + return list; +} + + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetPropertiesForPrefix(PropertiesObject* self, PyObject* args) +{ + PyObject* prefixObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &prefixObj)) + { + return 0; + } + + string prefix; + if(!getStringArg(prefixObj, "prefix", prefix)) + { + return 0; + } + + assert(self->properties); + Ice::PropertyDict dict; + try + { + dict = (*self->properties)->getPropertiesForPrefix(prefix); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(result.get()) + { + for(Ice::PropertyDict::iterator p = dict.begin(); p != dict.end(); ++p) + { + PyObjectHandle key = createString(p->first); + PyObjectHandle val = createString(p->second); + if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) + { + return 0; + } + } + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesSetProperty(PropertiesObject* self, PyObject* args) +{ + PyObject* keyObj; + PyObject* valueObj; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &keyObj, &valueObj)) + { + return 0; + } + + string key; + string value; + if(!getStringArg(keyObj, "key", key)) + { + return 0; + } + if(!getStringArg(valueObj, "value", value)) + { + return 0; + } + + assert(self->properties); + try + { + (*self->properties)->setProperty(key, value); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesGetCommandLineOptions(PropertiesObject* self) +{ + Ice::StringSeq options; + assert(self->properties); + try + { + options = (*self->properties)->getCommandLineOptions(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* list = PyList_New(0); + if(!list) + { + return 0; + } + if(!stringSeqToList(options, list)) + { + return 0; + } + + return list; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesParseCommandLineOptions(PropertiesObject* self, PyObject* args) +{ + PyObject* prefixObj; + PyObject* options; + if(!PyArg_ParseTuple(args, STRCAST("OO!"), &prefixObj, &PyList_Type, &options)) + { + return 0; + } + + Ice::StringSeq seq; + if(!listToStringSeq(options, seq)) + { + return 0; + } + + string prefix; + if(!getStringArg(prefixObj, "prefix", prefix)) + { + return 0; + } + + assert(self->properties); + Ice::StringSeq filteredSeq; + try + { + filteredSeq = (*self->properties)->parseCommandLineOptions(prefix, seq); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* list = PyList_New(0); + if(!list) + { + return 0; + } + if(!stringSeqToList(filteredSeq, list)) + { + return 0; + } + + return list; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesParseIceCommandLineOptions(PropertiesObject* self, PyObject* args) +{ + PyObject* options; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &PyList_Type, &options)) + { + return 0; + } + + Ice::StringSeq seq; + if(!listToStringSeq(options, seq)) + { + return 0; + } + + assert(self->properties); + Ice::StringSeq filteredSeq; + try + { + filteredSeq = (*self->properties)->parseIceCommandLineOptions(seq); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObject* list = PyList_New(0); + if(!list) + { + return 0; + } + if(!stringSeqToList(filteredSeq, list)) + { + return 0; + } + + return list; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesLoad(PropertiesObject* self, PyObject* args) +{ + PyObject* fileObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &fileObj)) + { + return 0; + } + + string file; + if(!getStringArg(fileObj, "file", file)) + { + return 0; + } + + assert(self->properties); + try + { + (*self->properties)->load(file); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +propertiesClone(PropertiesObject* self) +{ + Ice::PropertiesPtr properties; + assert(self->properties); + try + { + properties = (*self->properties)->clone(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProperties(properties); +} + +static PyMethodDef PropertyMethods[] = +{ + { STRCAST("getProperty"), reinterpret_cast<PyCFunction>(propertiesGetProperty), METH_VARARGS, + PyDoc_STR(STRCAST("getProperty(key) -> string")) }, + { STRCAST("getPropertyWithDefault"), reinterpret_cast<PyCFunction>(propertiesGetPropertyWithDefault), METH_VARARGS, + PyDoc_STR(STRCAST("getPropertyWithDefault(key, default) -> string")) }, + { STRCAST("getPropertyAsInt"), reinterpret_cast<PyCFunction>(propertiesGetPropertyAsInt), METH_VARARGS, + PyDoc_STR(STRCAST("getPropertyAsInt(key) -> int")) }, + { STRCAST("getPropertyAsIntWithDefault"), reinterpret_cast<PyCFunction>(propertiesGetPropertyAsIntWithDefault), + METH_VARARGS, PyDoc_STR(STRCAST("getPropertyAsIntWithDefault(key, default) -> int")) }, + { STRCAST("getPropertyAsList"), reinterpret_cast<PyCFunction>(propertiesGetPropertyAsList), METH_VARARGS, + PyDoc_STR(STRCAST("getPropertyAsList(key) -> list")) }, + { STRCAST("getPropertyAsListWithDefault"), reinterpret_cast<PyCFunction>(propertiesGetPropertyAsListWithDefault), + METH_VARARGS, PyDoc_STR(STRCAST("getPropertyAsListWithDefault(key, default) -> list")) }, + { STRCAST("getPropertiesForPrefix"), reinterpret_cast<PyCFunction>(propertiesGetPropertiesForPrefix), METH_VARARGS, + PyDoc_STR(STRCAST("getPropertiesForPrefix(prefix) -> dict")) }, + { STRCAST("setProperty"), reinterpret_cast<PyCFunction>(propertiesSetProperty), METH_VARARGS, + PyDoc_STR(STRCAST("setProperty(key, value) -> None")) }, + { STRCAST("getCommandLineOptions"), reinterpret_cast<PyCFunction>(propertiesGetCommandLineOptions), METH_NOARGS, + PyDoc_STR(STRCAST("getCommandLineOptions() -> list")) }, + { STRCAST("parseCommandLineOptions"), reinterpret_cast<PyCFunction>(propertiesParseCommandLineOptions), + METH_VARARGS, PyDoc_STR(STRCAST("parseCommandLineOptions(prefix, options) -> list")) }, + { STRCAST("parseIceCommandLineOptions"), reinterpret_cast<PyCFunction>(propertiesParseIceCommandLineOptions), + METH_VARARGS, PyDoc_STR(STRCAST("parseIceCommandLineOptions(prefix, options) -> list")) }, + { STRCAST("load"), reinterpret_cast<PyCFunction>(propertiesLoad), METH_VARARGS, + PyDoc_STR(STRCAST("load(file) -> None")) }, + { STRCAST("clone"), reinterpret_cast<PyCFunction>(propertiesClone), METH_NOARGS, + PyDoc_STR(STRCAST("clone() -> Ice.Properties")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject PropertiesType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.Properties"), /* tp_name */ + sizeof(PropertiesObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(propertiesDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + reinterpret_cast<reprfunc>(propertiesStr), /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + PropertyMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + reinterpret_cast<initproc>(propertiesInit), /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(propertiesNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initProperties(PyObject* module) +{ + if(PyType_Ready(&PropertiesType) < 0) + { + return false; + } + PyTypeObject* type = &PropertiesType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("Properties"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createProperties(const Ice::PropertiesPtr& props) +{ + PropertiesObject* obj = propertiesNew(&PropertiesType, 0, 0); + if(obj) + { + obj->properties = new Ice::PropertiesPtr(props); + } + return reinterpret_cast<PyObject*>(obj); +} + +Ice::PropertiesPtr +IcePy::getProperties(PyObject* p) +{ + PropertiesObject* obj = reinterpret_cast<PropertiesObject*>(p); + if(obj->properties) + { + return *obj->properties; + } + return 0; +} + +extern "C" +PyObject* +IcePy_createProperties(PyObject* /*self*/, PyObject* args) +{ + // + // Currently the same as "p = Ice.Properties()". + // + PyTypeObject* type = &PropertiesType; // Necessary to prevent GCC's strict-alias warnings. + return PyObject_Call(reinterpret_cast<PyObject*>(type), args, 0); +} diff --git a/python/modules/IcePy/Properties.h b/python/modules/IcePy/Properties.h new file mode 100644 index 00000000000..7246dd25ac4 --- /dev/null +++ b/python/modules/IcePy/Properties.h @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_PROPERTIES_H +#define ICEPY_PROPERTIES_H + +#include <Config.h> +#include <Ice/PropertiesF.h> + +namespace IcePy +{ + +extern PyTypeObject PropertiesType; + +bool initProperties(PyObject*); + +PyObject* createProperties(const Ice::PropertiesPtr&); + +Ice::PropertiesPtr getProperties(PyObject*); + +} + +extern "C" PyObject* IcePy_createProperties(PyObject*, PyObject*); + +#endif diff --git a/python/modules/IcePy/PropertiesAdmin.cpp b/python/modules/IcePy/PropertiesAdmin.cpp new file mode 100644 index 00000000000..80995d8c864 --- /dev/null +++ b/python/modules/IcePy/PropertiesAdmin.cpp @@ -0,0 +1,252 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <IceUtil/DisableWarnings.h> +#include <PropertiesAdmin.h> +#include <Util.h> +#include <Thread.h> +#include <Types.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +class UpdateCallbackWrapper : public Ice::PropertiesAdminUpdateCallback +{ +public: + + UpdateCallbackWrapper(PyObject*); + ~UpdateCallbackWrapper(); + + PyObject* getObject() const; + + void updated(const Ice::PropertyDict&); + +private: + + PyObject* _callback; +}; +typedef IceUtil::Handle<UpdateCallbackWrapper> UpdateCallbackWrapperPtr; + +struct NativePropertiesAdminObject +{ + PyObject_HEAD + Ice::NativePropertiesAdminPtr* admin; + vector<UpdateCallbackWrapperPtr>* callbacks; +}; + +} + +IcePy::UpdateCallbackWrapper::UpdateCallbackWrapper(PyObject* callback) : _callback(callback) +{ + Py_INCREF(_callback); +} + +IcePy::UpdateCallbackWrapper::~UpdateCallbackWrapper() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_callback); +} + +PyObject* +IcePy::UpdateCallbackWrapper::getObject() const +{ + return _callback; +} + +void +IcePy::UpdateCallbackWrapper::updated(const Ice::PropertyDict& dict) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle result = PyDict_New(); + if(result.get()) + { + for(Ice::PropertyDict::const_iterator p = dict.begin(); p != dict.end(); ++p) + { + PyObjectHandle key = createString(p->first); + PyObjectHandle val = createString(p->second); + if(!val.get() || PyDict_SetItem(result.get(), key.get(), val.get()) < 0) + { + return; + } + } + } + + PyObjectHandle obj = PyObject_CallMethod(_callback, STRCAST("updated"), STRCAST("O"), result.get()); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } +} + +#ifdef WIN32 +extern "C" +#endif +static NativePropertiesAdminObject* +nativePropertiesAdminNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("This object cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +nativePropertiesAdminDealloc(NativePropertiesAdminObject* self) +{ + delete self->admin; + delete self->callbacks; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +nativePropertiesAdminAddUpdateCB(NativePropertiesAdminObject* self, PyObject* args) +{ + PyObject* callbackType = lookupType("Ice.PropertiesAdminUpdateCallback"); + PyObject* callback; + if(!PyArg_ParseTuple(args, STRCAST("O!"), callbackType, &callback)) + { + return 0; + } + + (*self->callbacks).push_back(new UpdateCallbackWrapper(callback)); + (*self->admin)->addUpdateCallback((*self->callbacks).back()); + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +nativePropertiesAdminRemoveUpdateCB(NativePropertiesAdminObject* self, PyObject* args) +{ + PyObject* callbackType = lookupType("Ice.PropertiesAdminUpdateCallback"); + PyObject* callback; + if(!PyArg_ParseTuple(args, STRCAST("O!"), callbackType, &callback)) + { + return 0; + } + + for(vector<UpdateCallbackWrapperPtr>::const_iterator p = (*self->callbacks).begin(); p != (*self->callbacks).end(); + ++p) + { + if((*p)->getObject() == callback) + { + (*self->admin)->removeUpdateCallback(*p); + break; + } + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef NativePropertiesAdminMethods[] = +{ + { STRCAST("addUpdateCallback"), reinterpret_cast<PyCFunction>(nativePropertiesAdminAddUpdateCB), METH_VARARGS, + PyDoc_STR(STRCAST("addUpdateCallback(callback) -> None")) }, + { STRCAST("removeUpdateCallback"), reinterpret_cast<PyCFunction>(nativePropertiesAdminRemoveUpdateCB), METH_VARARGS, + PyDoc_STR(STRCAST("removeUpdateCallback(callback) -> None")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject NativePropertiesAdminType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.NativePropertiesAdmin"), /* tp_name */ + sizeof(NativePropertiesAdminObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(nativePropertiesAdminDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NativePropertiesAdminMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(nativePropertiesAdminNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initPropertiesAdmin(PyObject* module) +{ + if(PyType_Ready(&NativePropertiesAdminType) < 0) + { + return false; + } + PyTypeObject* type = &NativePropertiesAdminType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("NativePropertiesAdmin"), reinterpret_cast<PyObject*>(type)) < 0) + { + return false; + } + return true; +} + +PyObject* +IcePy::createNativePropertiesAdmin(const Ice::NativePropertiesAdminPtr& admin) +{ + PyTypeObject* type = &NativePropertiesAdminType; + + NativePropertiesAdminObject* p = reinterpret_cast<NativePropertiesAdminObject*>(type->tp_alloc(type, 0)); + if(!p) + { + return 0; + } + + p->admin = new Ice::NativePropertiesAdminPtr(admin); + p->callbacks = new vector<UpdateCallbackWrapperPtr>(); + return (PyObject*)p; +} diff --git a/python/modules/IcePy/PropertiesAdmin.h b/python/modules/IcePy/PropertiesAdmin.h new file mode 100644 index 00000000000..8479060cb9a --- /dev/null +++ b/python/modules/IcePy/PropertiesAdmin.h @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_PROPERTIES_ADMIN_H +#define ICEPY_PROPERTIES_ADMIN_H + +#include <Config.h> +#include <Ice/NativePropertiesAdmin.h> + +namespace IcePy +{ + +extern PyTypeObject NativePropertiesAdminType; + +bool initPropertiesAdmin(PyObject*); + +PyObject* createNativePropertiesAdmin(const Ice::NativePropertiesAdminPtr&); + +} + +#endif diff --git a/python/modules/IcePy/Proxy.cpp b/python/modules/IcePy/Proxy.cpp new file mode 100644 index 00000000000..293c3c16de8 --- /dev/null +++ b/python/modules/IcePy/Proxy.cpp @@ -0,0 +1,2689 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#include <IceUtil/DisableWarnings.h> +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Proxy.h> +#include <structmember.h> +#include <Communicator.h> +#include <Connection.h> +#include <Endpoint.h> +#include <Operation.h> +#include <Thread.h> +#include <Util.h> +#include <Ice/Communicator.h> +#include <Ice/LocalException.h> +#include <Ice/Locator.h> +#include <Ice/Proxy.h> +#include <Ice/Router.h> + +using namespace std; +using namespace IcePy; + +namespace IcePy +{ + +struct ProxyObject +{ + PyObject_HEAD + Ice::ObjectPrx* proxy; + Ice::CommunicatorPtr* communicator; +}; + +} + +// +// Proxy implementation. +// +static ProxyObject* +allocateProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) +{ + PyTypeObject* typeObj = reinterpret_cast<PyTypeObject*>(type); + ProxyObject* p = reinterpret_cast<ProxyObject*>(typeObj->tp_alloc(typeObj, 0)); + if(!p) + { + return 0; + } + + // + // Disabling collocation optimization can cause subtle problems with proxy + // comparison (such as in RouterInfo::get) if a proxy from IcePy is + // compared with a proxy from Ice/C++. + // + //if(proxy) + //{ + // p->proxy = new Ice::ObjectPrx(proxy->ice_collocationOptimized(false)); + //} + // + p->proxy = new Ice::ObjectPrx(proxy); + p->communicator = new Ice::CommunicatorPtr(communicator); + + return p; +} + +#ifdef WIN32 +extern "C" +#endif +static ProxyObject* +proxyNew(PyTypeObject* /*type*/, PyObject* /*args*/, PyObject* /*kwds*/) +{ + PyErr_Format(PyExc_RuntimeError, STRCAST("A proxy cannot be created directly")); + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static void +proxyDealloc(ProxyObject* self) +{ + delete self->proxy; + delete self->communicator; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyCompare(ProxyObject* p1, PyObject* other, int op) +{ + bool result = false; + + if(PyObject_TypeCheck(other, &ProxyType)) + { + ProxyObject* p2 = reinterpret_cast<ProxyObject*>(other); + + switch(op) + { + case Py_EQ: + result = *p1->proxy == *p2->proxy; + break; + case Py_NE: + result = *p1->proxy != *p2->proxy; + break; + case Py_LE: + result = *p1->proxy <= *p2->proxy; + break; + case Py_GE: + result = *p1->proxy >= *p2->proxy; + break; + case Py_LT: + result = *p1->proxy < *p2->proxy; + break; + case Py_GT: + result = *p1->proxy > *p2->proxy; + break; + } + } + else if(other == Py_None) + { + result = op == Py_NE || op == Py_GE || op == Py_GT; + } + else + { + if(op == Py_EQ) + { + result = false; + } + else if(op == Py_NE) + { + result = true; + } + else + { + PyErr_Format(PyExc_TypeError, "can't compare %s to %s", Py_TYPE(p1)->tp_name, Py_TYPE(other)->tp_name); + return 0; + } + } + + PyObject* r = result ? getTrue() : getFalse(); + Py_INCREF(r); + return r; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyRepr(ProxyObject* self) +{ + string str = (*self->proxy)->ice_toString(); + return createString(str); +} + +#ifdef WIN32 +extern "C" +#endif +static long +proxyHash(ProxyObject* self) +{ + return static_cast<long>((*self->proxy)->__hash()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetCommunicator(ProxyObject* self) +{ + return getCommunicatorWrapper(*self->communicator); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsA(ProxyObject* self, PyObject* args) +{ + PyObject* type; + PyObject* ctx = Py_None; + if(!PyArg_ParseTuple(args, STRCAST("O|O!"), &type, &PyDict_Type, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((O), O)"), type, ctx); + + return invokeBuiltin(reinterpret_cast<PyObject*>(self), "ice_isA", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceIsA(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + static char* argNames[] = + { + const_cast<char*>("type"), + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + const_cast<char*>("_ctx"), + 0 + }; + PyObject* type; + PyObject* response = Py_None; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + PyObject* ctx = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("O|OOOO"), argNames, &type, &response, &ex, &sent, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: + // + // ((params...), response|None, ex|None, sent|None, ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((O), O, O, O, O)"), type, response, ex, sent, ctx); + + return beginBuiltin(reinterpret_cast<PyObject*>(self), "ice_isA", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceIsA(ProxyObject* self, PyObject* args) +{ + return endBuiltin(reinterpret_cast<PyObject*>(self), "ice_isA", args); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIcePing(ProxyObject* self, PyObject* args) +{ + PyObject* ctx = Py_None; + if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx); + + return invokeBuiltin(reinterpret_cast<PyObject*>(self), "ice_ping", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIcePing(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + static char* argNames[] = + { + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + const_cast<char*>("_ctx"), + 0 + }; + PyObject* response = Py_None; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + PyObject* ctx = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OOOO"), argNames, &response, &ex, &sent, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: + // + // ((params...), response|None, ex|None, sent|None, ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O, O, O, O)"), response, ex, sent, ctx); + + return beginBuiltin(reinterpret_cast<PyObject*>(self), "ice_ping", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIcePing(ProxyObject* self, PyObject* args) +{ + return endBuiltin(reinterpret_cast<PyObject*>(self), "ice_ping", args); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIds(ProxyObject* self, PyObject* args) +{ + PyObject* ctx = Py_None; + if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx); + + return invokeBuiltin(reinterpret_cast<PyObject*>(self), "ice_ids", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceIds(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + static char* argNames[] = + { + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + const_cast<char*>("_ctx"), + 0 + }; + PyObject* response = Py_None; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + PyObject* ctx = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OOOO"), argNames, &response, &ex, &sent, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: + // + // ((params...), response|None, ex|None, sent|None, ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O, O, O, O)"), response, ex, sent, ctx); + + return beginBuiltin(reinterpret_cast<PyObject*>(self), "ice_ids", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceIds(ProxyObject* self, PyObject* args) +{ + return endBuiltin(reinterpret_cast<PyObject*>(self), "ice_ids", args); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceId(ProxyObject* self, PyObject* args) +{ + PyObject* ctx = Py_None; + if(!PyArg_ParseTuple(args, STRCAST("|O!"), &PyDict_Type, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: ((params...), ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O)"), ctx); + + return invokeBuiltin(reinterpret_cast<PyObject*>(self), "ice_id", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceId(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + static char* argNames[] = + { + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + const_cast<char*>("_ctx"), + 0 + }; + PyObject* response = Py_None; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + PyObject* ctx = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OOOO"), argNames, &response, &ex, &sent, &ctx)) + { + return 0; + } + + // + // We need to reformat the arguments to match what is used by the generated code: + // + // ((params...), response|None, ex|None, sent|None, ctx|None) + // + PyObjectHandle newArgs = Py_BuildValue(STRCAST("((), O, O, O, O)"), response, ex, sent, ctx); + + return beginBuiltin(reinterpret_cast<PyObject*>(self), "ice_id", newArgs.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceId(ProxyObject* self, PyObject* args) +{ + return endBuiltin(reinterpret_cast<PyObject*>(self), "ice_id", args); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetIdentity(ProxyObject* self) +{ + assert(self->proxy); + + Ice::Identity id; + try + { + id = (*self->proxy)->ice_getIdentity(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createIdentity(id); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIdentity(ProxyObject* self, PyObject* args) +{ + PyObject* identityType = lookupType("Ice.Identity"); + assert(identityType); + PyObject* id; + if(!PyArg_ParseTuple(args, STRCAST("O!"), identityType, &id)) + { + return 0; + } + + assert(self->proxy); + + Ice::Identity ident; + if(!getIdentity(id, ident)) + { + return 0; + } + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_identity(ident); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetContext(ProxyObject* self) +{ + assert(self->proxy); + + Ice::Context ctx; + try + { + ctx = (*self->proxy)->ice_getContext(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle result = PyDict_New(); + if(result.get() && contextToDictionary(ctx, result.get())) + { + return result.release(); + } + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceContext(ProxyObject* self, PyObject* args) +{ + PyObject* dict; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &PyDict_Type, &dict)) + { + return 0; + } + + assert(self->proxy); + + Ice::Context ctx; + if(!dictionaryToContext(dict, ctx)) + { + return 0; + } + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_context(ctx); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetFacet(ProxyObject* self) +{ + assert(self->proxy); + + string facet; + try + { + facet = (*self->proxy)->ice_getFacet(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(facet); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceFacet(ProxyObject* self, PyObject* args) +{ + PyObject* facetObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &facetObj)) + { + return 0; + } + + string facet; + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_facet(facet); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetAdapterId(ProxyObject* self) +{ + assert(self->proxy); + + string id; + try + { + id = (*self->proxy)->ice_getAdapterId(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createString(id); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceAdapterId(ProxyObject* self, PyObject* args) +{ + PyObject* idObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &idObj)) + { + return 0; + } + + string id; + if(!getStringArg(idObj, "id", id)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_adapterId(id); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetEndpoints(ProxyObject* self) +{ + assert(self->proxy); + + Ice::EndpointSeq endpoints; + try + { + endpoints = (*self->proxy)->ice_getEndpoints(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + int count = static_cast<int>(endpoints.size()); + PyObjectHandle result = PyTuple_New(count); + int i = 0; + for(Ice::EndpointSeq::const_iterator p = endpoints.begin(); p != endpoints.end(); ++p, ++i) + { + PyObjectHandle endp = createEndpoint(*p); + if(!endp.get()) + { + return 0; + } + PyTuple_SET_ITEM(result.get(), i, endp.release()); // PyTuple_SET_ITEM steals a reference. + } + + return result.release(); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceEndpoints(ProxyObject* self, PyObject* args) +{ + PyObject* endpoints; + if(!PyArg_ParseTuple(args, STRCAST("O"), &endpoints)) + { + return 0; + } + + if(!PyTuple_Check(endpoints) && !PyList_Check(endpoints)) + { + PyErr_Format(PyExc_ValueError, STRCAST("argument must be a tuple or list")); + return 0; + } + + assert(self->proxy); + + Ice::EndpointSeq seq; + Py_ssize_t sz = PySequence_Fast_GET_SIZE(endpoints); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* p = PySequence_Fast_GET_ITEM(endpoints, i); + PyTypeObject* type = &EndpointType; // Necessary to prevent GCC's strict-alias warnings. + if(!PyObject_IsInstance(p, reinterpret_cast<PyObject*>(type))) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected element of type Ice.Endpoint")); + return 0; + } + Ice::EndpointPtr endp = getEndpoint(p); + if(!endp) + { + return 0; + } + seq.push_back(endp); + } + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_endpoints(seq); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetLocatorCacheTimeout(ProxyObject* self) +{ + assert(self->proxy); + + try + { + Ice::Int timeout = (*self->proxy)->ice_getLocatorCacheTimeout(); + return PyLong_FromLong(timeout); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetInvocationTimeout(ProxyObject* self) +{ + assert(self->proxy); + + try + { + Ice::Int timeout = (*self->proxy)->ice_getInvocationTimeout(); + return PyLong_FromLong(timeout); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetConnectionId(ProxyObject* self) +{ + assert(self->proxy); + + try + { + string connectionId = (*self->proxy)->ice_getConnectionId(); + return createString(connectionId); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceLocatorCacheTimeout(ProxyObject* self, PyObject* args) +{ + int timeout; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_locatorCacheTimeout(timeout); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + return 0; + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceInvocationTimeout(ProxyObject* self, PyObject* args) +{ + int timeout; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_invocationTimeout(timeout); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + return 0; + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsConnectionCached(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isConnectionCached() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceConnectionCached(ProxyObject* self, PyObject* args) +{ + PyObject* flag; + if(!PyArg_ParseTuple(args, STRCAST("O"), &flag)) + { + return 0; + } + + int n = PyObject_IsTrue(flag); + if(n < 0) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_connectionCached(n == 1); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetEndpointSelection(ProxyObject* self) +{ + PyObject* cls = lookupType("Ice.EndpointSelectionType"); + assert(cls); + + PyObjectHandle rnd = PyObject_GetAttrString(cls, STRCAST("Random")); + PyObjectHandle ord = PyObject_GetAttrString(cls, STRCAST("Ordered")); + assert(rnd.get()); + assert(ord.get()); + + assert(self->proxy); + + PyObject* type; + try + { + Ice::EndpointSelectionType val = (*self->proxy)->ice_getEndpointSelection(); + if(val == Ice::Random) + { + type = rnd.get(); + } + else + { + type = ord.get(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(type); + return type; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceEndpointSelection(ProxyObject* self, PyObject* args) +{ + PyObject* cls = lookupType("Ice.EndpointSelectionType"); + assert(cls); + PyObject* type; + if(!PyArg_ParseTuple(args, STRCAST("O!"), cls, &type)) + { + return 0; + } + + Ice::EndpointSelectionType val; + PyObjectHandle rnd = PyObject_GetAttrString(cls, STRCAST("Random")); + PyObjectHandle ord = PyObject_GetAttrString(cls, STRCAST("Ordered")); + assert(rnd.get()); + assert(ord.get()); + if(rnd.get() == type) + { + val = Ice::Random; + } + else if(ord.get() == type) + { + val = Ice::Ordered; + } + else + { + PyErr_Format(PyExc_ValueError, STRCAST("ice_endpointSelection requires Random or Ordered")); + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_endpointSelection(val); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsSecure(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isSecure() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceSecure(ProxyObject* self, PyObject* args) +{ + PyObject* flag; + if(!PyArg_ParseTuple(args, STRCAST("O"), &flag)) + { + return 0; + } + + int n = PyObject_IsTrue(flag); + if(n < 0) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_secure(n == 1); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetEncodingVersion(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* version; + try + { + version = IcePy::createEncodingVersion((*self->proxy)->ice_getEncodingVersion()); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(version); + return version; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceEncodingVersion(ProxyObject* self, PyObject* args) +{ + Ice::EncodingVersion val; + if(!getEncodingVersion(args, val)) + { + PyErr_Format(PyExc_ValueError, STRCAST("ice_encodingVersion requires an encoding version")); + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_encodingVersion(val); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsPreferSecure(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isPreferSecure() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIcePreferSecure(ProxyObject* self, PyObject* args) +{ + PyObject* flag; + if(!PyArg_ParseTuple(args, STRCAST("O"), &flag)) + { + return 0; + } + + int n = PyObject_IsTrue(flag); + if(n < 0) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_preferSecure(n == 1); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetRouter(ProxyObject* self) +{ + assert(self->proxy); + + Ice::RouterPrx router; + try + { + router = (*self->proxy)->ice_getRouter(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!router) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* routerProxyType = lookupType("Ice.RouterPrx"); + assert(routerProxyType); + return createProxy(router, *self->communicator, routerProxyType); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceRouter(ProxyObject* self, PyObject* args) +{ + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O"), &p)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "ice_router", "rtr", proxy, "Ice.RouterPrx")) + { + return 0; + } + + Ice::RouterPrx router = Ice::RouterPrx::uncheckedCast(proxy); + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_router(router); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetLocator(ProxyObject* self) +{ + assert(self->proxy); + + Ice::LocatorPrx locator; + try + { + locator = (*self->proxy)->ice_getLocator(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(!locator) + { + Py_INCREF(Py_None); + return Py_None; + } + + PyObject* locatorProxyType = lookupType("Ice.LocatorPrx"); + assert(locatorProxyType); + return createProxy(locator, *self->communicator, locatorProxyType); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceLocator(ProxyObject* self, PyObject* args) +{ + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O"), &p)) + { + return 0; + } + + Ice::ObjectPrx proxy; + if(!getProxyArg(p, "ice_locator", "loc", proxy, "Ice.LocatorPrx")) + { + return 0; + } + + Ice::LocatorPrx locator = Ice::LocatorPrx::uncheckedCast(proxy); + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_locator(locator); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceTwoway(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_twoway(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsTwoway(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isTwoway() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceOneway(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_oneway(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsOneway(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isOneway() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceBatchOneway(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_batchOneway(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsBatchOneway(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isBatchOneway() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceDatagram(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_datagram(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsDatagram(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isDatagram() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceBatchDatagram(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_batchDatagram(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsBatchDatagram(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isBatchDatagram() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceCompress(ProxyObject* self, PyObject* args) +{ + PyObject* flag; + if(!PyArg_ParseTuple(args, STRCAST("O"), &flag)) + { + return 0; + } + + int n = PyObject_IsTrue(flag); + if(n < 0) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_compress(n == 1); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceTimeout(ProxyObject* self, PyObject* args) +{ + int timeout; + if(!PyArg_ParseTuple(args, STRCAST("i"), &timeout)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_timeout(timeout); + } + catch(const IceUtil::IllegalArgumentException& ex) + { + PyErr_Format(PyExc_RuntimeError, "%s", STRCAST(ex.reason().c_str())); + return 0; + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceIsCollocationOptimized(ProxyObject* self) +{ + assert(self->proxy); + + PyObject* b; + try + { + b = (*self->proxy)->ice_isCollocationOptimized() ? getTrue() : getFalse(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(b); + return b; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceCollocationOptimized(ProxyObject* self, PyObject* args) +{ + PyObject* flag; + if(!PyArg_ParseTuple(args, STRCAST("O"), &flag)) + { + return 0; + } + + int n = PyObject_IsTrue(flag); + if(n < 0) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_collocationOptimized(n == 1); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceConnectionId(ProxyObject* self, PyObject* args) +{ + PyObject* idObj; + if(!PyArg_ParseTuple(args, STRCAST("O"), &idObj)) + { + return 0; + } + + string id; + if(!getStringArg(idObj, "id", id)) + { + return 0; + } + + assert(self->proxy); + + Ice::ObjectPrx newProxy; + try + { + newProxy = (*self->proxy)->ice_connectionId(id); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + return createProxy(newProxy, *self->communicator, reinterpret_cast<PyObject*>(Py_TYPE(self))); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetConnection(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ConnectionPtr con; + try + { + con = (*self->proxy)->ice_getConnection(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(con) + { + return createConnection(con, *self->communicator); + } + else + { + Py_INCREF(Py_None); + return Py_None; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceGetConnection(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + assert(self->proxy); + + static char* argNames[] = + { + const_cast<char*>("_response"), + const_cast<char*>("_ex"), + 0 + }; + + PyObject* response = Py_None; + PyObject* ex = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &response, &ex)) + { + return 0; + } + + if(response == Py_None) + { + response = 0; + } + if(ex == Py_None) + { + ex = 0; + } + + if(!response && ex) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("response callback must also be provided when exception callback is used")); + return 0; + } + + Ice::Callback_Object_ice_getConnectionPtr cb; + if(response || ex) + { + GetConnectionCallbackPtr d = new GetConnectionCallback(*self->communicator, response, ex, "ice_getConnection"); + cb = Ice::newCallback_Object_ice_getConnection(d, &GetConnectionCallback::response, + &GetConnectionCallback::exception); + } + + Ice::AsyncResultPtr result; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + + if(cb) + { + result = (*self->proxy)->begin_ice_getConnection(cb); + } + else + { + result = (*self->proxy)->begin_ice_getConnection(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle communicator = getCommunicatorWrapper(*self->communicator); + return createAsyncResult(result, reinterpret_cast<PyObject*>(self), 0, communicator.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceGetConnection(ProxyObject* self, PyObject* args) +{ + assert(self->proxy); + + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + Ice::AsyncResultPtr r = getAsyncResult(result); + Ice::ConnectionPtr con; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + con = (*self->proxy)->end_ice_getConnection(r); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(con) + { + return createConnection(con, *self->communicator); + } + else + { + Py_INCREF(Py_None); + return Py_None; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceGetCachedConnection(ProxyObject* self) +{ + assert(self->proxy); + + Ice::ConnectionPtr con; + try + { + con = (*self->proxy)->ice_getCachedConnection(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(con) + { + return createConnection(con, *self->communicator); + } + else + { + Py_INCREF(Py_None); + return Py_None; + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceFlushBatchRequests(ProxyObject* self) +{ + assert(self->proxy); + + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + (*self->proxy)->ice_flushBatchRequests(); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceFlushBatchRequests(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + assert(self->proxy); + + static char* argNames[] = + { + const_cast<char*>("_ex"), + const_cast<char*>("_sent"), + 0 + }; + PyObject* ex = Py_None; + PyObject* sent = Py_None; + if(!PyArg_ParseTupleAndKeywords(args, kwds, STRCAST("|OO"), argNames, &ex, &sent)) + { + return 0; + } + + if(ex == Py_None) + { + ex = 0; + } + if(sent == Py_None) + { + sent = 0; + } + + if(!ex && sent) + { + PyErr_Format(PyExc_RuntimeError, + STRCAST("exception callback must also be provided when sent callback is used")); + return 0; + } + + Ice::Callback_Object_ice_flushBatchRequestsPtr cb; + if(ex || sent) + { + FlushCallbackPtr d = new FlushCallback(ex, sent, "ice_flushBatchRequests"); + cb = Ice::newCallback_Object_ice_flushBatchRequests(d, &FlushCallback::exception, &FlushCallback::sent); + } + + Ice::AsyncResultPtr result; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + + if(cb) + { + result = (*self->proxy)->begin_ice_flushBatchRequests(cb); + } + else + { + result = (*self->proxy)->begin_ice_flushBatchRequests(); + } + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + PyObjectHandle communicator = getCommunicatorWrapper(*self->communicator); + return createAsyncResult(result, reinterpret_cast<PyObject*>(self), 0, communicator.get()); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceFlushBatchRequests(ProxyObject* self, PyObject* args) +{ + assert(self->proxy); + + PyObject* result; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &AsyncResultType, &result)) + { + return 0; + } + + Ice::AsyncResultPtr r = getAsyncResult(result); + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during blocking invocations. + (*self->proxy)->end_ice_flushBatchRequests(r); + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + Py_INCREF(Py_None); + return Py_None; +} + +namespace IcePy +{ +class AMI_Object_ice_flushBatchRequestsI : public IceUtil::Shared +{ +public: + + AMI_Object_ice_flushBatchRequestsI(PyObject*); + ~AMI_Object_ice_flushBatchRequestsI(); + + void exception(const Ice::Exception&); + void sent(bool); + +protected: + + PyObject* _callback; +}; +typedef IceUtil::Handle<AMI_Object_ice_flushBatchRequestsI> AMI_Object_ice_flushBatchRequestsIPtr; + +AMI_Object_ice_flushBatchRequestsI::AMI_Object_ice_flushBatchRequestsI(PyObject* callback) : + _callback(callback) +{ + Py_INCREF(callback); +} + +AMI_Object_ice_flushBatchRequestsI::~AMI_Object_ice_flushBatchRequestsI() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + Py_DECREF(_callback); +} + +void +AMI_Object_ice_flushBatchRequestsI::exception(const Ice::Exception& ex) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + const string methodName = "ice_exception"; + if(!PyObject_HasAttrString(_callback, STRCAST(methodName.c_str()))) + { + ostringstream ostr; + ostr << "AMI callback object for ice_flushBatchRequests does not define " << methodName << "()"; + string str = ostr.str(); + PyErr_Warn(PyExc_RuntimeWarning, const_cast<char*>(str.c_str())); + } + else + { + PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str())); + assert(method.get()); + PyObjectHandle exh = convertException(ex); + assert(exh.get()); + + PyObjectHandle args = Py_BuildValue(STRCAST("(O)"), exh.get()); + PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); + if(PyErr_Occurred()) + { + PyErr_Print(); + } + } +} + +void +AMI_Object_ice_flushBatchRequestsI::sent(bool) +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + const string methodName = "ice_sent"; + if(PyObject_HasAttrString(_callback, STRCAST(methodName.c_str()))) + { + PyObjectHandle method = PyObject_GetAttrString(_callback, STRCAST(methodName.c_str())); + assert(method.get()); + PyObjectHandle args = PyTuple_New(0); + PyObjectHandle tmp = PyObject_Call(method.get(), args.get(), 0); + if(PyErr_Occurred()) + { + PyErr_Print(); + } + } +} +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceInvoke(ProxyObject* self, PyObject* args) +{ + return iceInvoke(reinterpret_cast<PyObject*>(self), args); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyBeginIceInvoke(ProxyObject* self, PyObject* args, PyObject* kwds) +{ + return beginIceInvoke(reinterpret_cast<PyObject*>(self), args, kwds); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyEndIceInvoke(ProxyObject* self, PyObject* args) +{ + return endIceInvoke(reinterpret_cast<PyObject*>(self), args); +} + +static PyObject* +checkedCastImpl(ProxyObject* p, const string& id, PyObject* facet, PyObject* ctx, PyObject* type) +{ + Ice::ObjectPrx target; + if(!facet || facet == Py_None) + { + target = *p->proxy; + } + else + { + string facetStr = getString(facet); + target = (*p->proxy)->ice_facet(facetStr); + } + + bool b = false; + try + { + AllowThreads allowThreads; // Release Python's global interpreter lock during remote invocations. + if(!ctx || ctx == Py_None) + { + b = target->ice_isA(id); + } + else + { + Ice::Context c; + if(!dictionaryToContext(ctx, c)) + { + return 0; + } + b = target->ice_isA(id, c); + } + } + catch(const Ice::FacetNotExistException&) + { + // Ignore. + } + catch(const Ice::Exception& ex) + { + setPythonException(ex); + return 0; + } + + if(b) + { + return createProxy(target, *p->communicator, type); + } + + Py_INCREF(Py_None); + return Py_None; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceCheckedCast(PyObject* type, PyObject* args) +{ + // + // ice_checkedCast is called from generated code, therefore we always expect + // to receive four arguments. + // + PyObject* obj; + char* id; + PyObject* facetOrCtx = 0; + PyObject* ctx = 0; + if(!PyArg_ParseTuple(args, STRCAST("OsOO"), &obj, &id, &facetOrCtx, &ctx)) + { + return 0; + } + + if(obj == Py_None) + { + Py_INCREF(Py_None); + return Py_None; + } + + if(!checkProxy(obj)) + { + PyErr_Format(PyExc_ValueError, STRCAST("ice_checkedCast requires a proxy argument")); + return 0; + } + + PyObject* facet = 0; + + if(checkString(facetOrCtx)) + { + facet = facetOrCtx; + } + else if(PyDict_Check(facetOrCtx)) + { + if(ctx != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("facet argument to checkedCast must be a string")); + return 0; + } + ctx = facetOrCtx; + } + else if(facetOrCtx != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("second argument to checkedCast must be a facet or context")); + return 0; + } + + if(ctx != Py_None && !PyDict_Check(ctx)) + { + PyErr_Format(PyExc_ValueError, STRCAST("context argument to checkedCast must be a dictionary")); + return 0; + } + + return checkedCastImpl(reinterpret_cast<ProxyObject*>(obj), id, facet, ctx, type); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceUncheckedCast(PyObject* type, PyObject* args) +{ + // + // ice_uncheckedCast is called from generated code, therefore we always expect + // to receive two arguments. + // + PyObject* obj; + char* facet = 0; + if(!PyArg_ParseTuple(args, STRCAST("Oz"), &obj, &facet)) + { + return 0; + } + + if(obj == Py_None) + { + Py_INCREF(Py_None); + return Py_None; + } + + if(!checkProxy(obj)) + { + PyErr_Format(PyExc_ValueError, STRCAST("ice_uncheckedCast requires a proxy argument")); + return 0; + } + + ProxyObject* p = reinterpret_cast<ProxyObject*>(obj); + + if(facet) + { + return createProxy((*p->proxy)->ice_facet(facet), *p->communicator, type); + } + else + { + return createProxy(*p->proxy, *p->communicator, type); + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyCheckedCast(PyObject* /*self*/, PyObject* args) +{ + PyObject* obj; + PyObject* arg1 = 0; + PyObject* arg2 = 0; + if(!PyArg_ParseTuple(args, STRCAST("O|OO"), &obj, &arg1, &arg2)) + { + return 0; + } + + if(obj == Py_None) + { + Py_INCREF(Py_None); + return Py_None; + } + + if(!checkProxy(obj)) + { + PyErr_Format(PyExc_ValueError, STRCAST("checkedCast requires a proxy argument")); + return 0; + } + + PyObject* facet = 0; + PyObject* ctx = 0; + + if(arg1 != 0 && arg2 != 0) + { + if(arg1 == Py_None) + { + arg1 = 0; + } + + if(arg2 == Py_None) + { + arg2 = 0; + } + + if(arg1 != 0) + { + if(!checkString(arg1)) + { + PyErr_Format(PyExc_ValueError, STRCAST("facet argument to checkedCast must be a string")); + return 0; + } + facet = arg1; + } + + if(arg2 != 0 && !PyDict_Check(arg2)) + { + PyErr_Format(PyExc_ValueError, STRCAST("context argument to checkedCast must be a dictionary")); + return 0; + } + ctx = arg2; + } + else if(arg1 != 0 && arg1 != Py_None) + { + if(checkString(arg1)) + { + facet = arg1; + } + else if(PyDict_Check(arg1)) + { + ctx = arg1; + } + else + { + PyErr_Format(PyExc_ValueError, STRCAST("second argument to checkedCast must be a facet or context")); + return 0; + } + } + + return checkedCastImpl(reinterpret_cast<ProxyObject*>(obj), "::Ice::Object", facet, ctx, 0); +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyUncheckedCast(PyObject* /*self*/, PyObject* args) +{ + PyObject* obj; + PyObject* facetObj = 0; + if(!PyArg_ParseTuple(args, STRCAST("O|O"), &obj, &facetObj)) + { + return 0; + } + + if(obj == Py_None) + { + Py_INCREF(Py_None); + return Py_None; + } + + string facet; + if(facetObj) + { + if(!getStringArg(facetObj, "facet", facet)) + { + return 0; + } + } + + if(!checkProxy(obj)) + { + PyErr_Format(PyExc_ValueError, STRCAST("uncheckedCast requires a proxy argument")); + return 0; + } + + ProxyObject* p = reinterpret_cast<ProxyObject*>(obj); + + if(facetObj) + { + return createProxy((*p->proxy)->ice_facet(facet), *p->communicator); + } + else + { + return createProxy(*p->proxy, *p->communicator); + } +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +proxyIceStaticId(PyObject* /*self*/) +{ + return createString(Ice::Object::ice_staticId()); +} + +static PyMethodDef ProxyMethods[] = +{ + { STRCAST("ice_getCommunicator"), reinterpret_cast<PyCFunction>(proxyIceGetCommunicator), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getCommunicator() -> Ice.Communicator")) }, + { STRCAST("ice_toString"), reinterpret_cast<PyCFunction>(proxyRepr), METH_NOARGS, + PyDoc_STR(STRCAST("ice_toString() -> string")) }, + { STRCAST("ice_isA"), reinterpret_cast<PyCFunction>(proxyIceIsA), METH_VARARGS, + PyDoc_STR(STRCAST("ice_isA(type, [ctx]) -> bool")) }, + { STRCAST("begin_ice_isA"), reinterpret_cast<PyCFunction>(proxyBeginIceIsA), METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_ice_isA(type[, _response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_isA"), reinterpret_cast<PyCFunction>(proxyEndIceIsA), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_isA(Ice.AsyncResult) -> bool")) }, + { STRCAST("ice_ping"), reinterpret_cast<PyCFunction>(proxyIcePing), METH_VARARGS, + PyDoc_STR(STRCAST("ice_ping([ctx]) -> None")) }, + { STRCAST("begin_ice_ping"), reinterpret_cast<PyCFunction>(proxyBeginIcePing), METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_ice_ping([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_ping"), reinterpret_cast<PyCFunction>(proxyEndIcePing), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_ping(Ice.AsyncResult) -> None")) }, + { STRCAST("ice_ids"), reinterpret_cast<PyCFunction>(proxyIceIds), METH_VARARGS, + PyDoc_STR(STRCAST("ice_ids([ctx]) -> list")) }, + { STRCAST("begin_ice_ids"), reinterpret_cast<PyCFunction>(proxyBeginIceIds), METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_ice_ids([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_ids"), reinterpret_cast<PyCFunction>(proxyEndIceIds), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_ids(Ice.AsyncResult) -> list")) }, + { STRCAST("ice_id"), reinterpret_cast<PyCFunction>(proxyIceId), METH_VARARGS, + PyDoc_STR(STRCAST("ice_id([ctx]) -> string")) }, + { STRCAST("begin_ice_id"), reinterpret_cast<PyCFunction>(proxyBeginIceId), METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_ice_id([_response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_id"), reinterpret_cast<PyCFunction>(proxyEndIceId), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_id(Ice.AsyncResult) -> string")) }, + { STRCAST("ice_getIdentity"), reinterpret_cast<PyCFunction>(proxyIceGetIdentity), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getIdentity() -> Ice.Identity")) }, + { STRCAST("ice_identity"), reinterpret_cast<PyCFunction>(proxyIceIdentity), METH_VARARGS, + PyDoc_STR(STRCAST("ice_identity(id) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getContext"), reinterpret_cast<PyCFunction>(proxyIceGetContext), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getContext() -> dict")) }, + { STRCAST("ice_context"), reinterpret_cast<PyCFunction>(proxyIceContext), METH_VARARGS, + PyDoc_STR(STRCAST("ice_context(dict) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getFacet"), reinterpret_cast<PyCFunction>(proxyIceGetFacet), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getFacet() -> string")) }, + { STRCAST("ice_facet"), reinterpret_cast<PyCFunction>(proxyIceFacet), METH_VARARGS, + PyDoc_STR(STRCAST("ice_facet(string) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getAdapterId"), reinterpret_cast<PyCFunction>(proxyIceGetAdapterId), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getAdapterId() -> string")) }, + { STRCAST("ice_adapterId"), reinterpret_cast<PyCFunction>(proxyIceAdapterId), METH_VARARGS, + PyDoc_STR(STRCAST("ice_adapterId(string) -> proxy")) }, + { STRCAST("ice_getEndpoints"), reinterpret_cast<PyCFunction>(proxyIceGetEndpoints), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getEndpoints() -> tuple")) }, + { STRCAST("ice_endpoints"), reinterpret_cast<PyCFunction>(proxyIceEndpoints), METH_VARARGS, + PyDoc_STR(STRCAST("ice_endpoints(tuple) -> proxy")) }, + { STRCAST("ice_getLocatorCacheTimeout"), reinterpret_cast<PyCFunction>(proxyIceGetLocatorCacheTimeout), + METH_NOARGS, PyDoc_STR(STRCAST("ice_getLocatorCacheTimeout() -> int")) }, + { STRCAST("ice_getInvocationTimeout"), reinterpret_cast<PyCFunction>(proxyIceGetInvocationTimeout), + METH_NOARGS, PyDoc_STR(STRCAST("ice_getInvocationTimeout() -> int")) }, + { STRCAST("ice_getConnectionId"), reinterpret_cast<PyCFunction>(proxyIceGetConnectionId), + METH_NOARGS, PyDoc_STR(STRCAST("ice_getConnectionId() -> string")) }, + { STRCAST("ice_isCollocationOptimized"), reinterpret_cast<PyCFunction>(proxyIceIsCollocationOptimized), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isCollocationOptimized() -> bool")) }, + { STRCAST("ice_collocationOptimized"), reinterpret_cast<PyCFunction>(proxyIceCollocationOptimized), METH_VARARGS, + PyDoc_STR(STRCAST("ice_collocationOptimized(bool) -> Ice.ObjectPrx")) }, + { STRCAST("ice_locatorCacheTimeout"), reinterpret_cast<PyCFunction>(proxyIceLocatorCacheTimeout), METH_VARARGS, + PyDoc_STR(STRCAST("ice_locatorCacheTimeout(int) -> Ice.ObjectPrx")) }, + { STRCAST("ice_invocationTimeout"), reinterpret_cast<PyCFunction>(proxyIceInvocationTimeout), METH_VARARGS, + PyDoc_STR(STRCAST("ice_invocationTimeout(int) -> Ice.ObjectPrx")) }, + { STRCAST("ice_isConnectionCached"), reinterpret_cast<PyCFunction>(proxyIceIsConnectionCached), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isConnectionCached() -> bool")) }, + { STRCAST("ice_connectionCached"), reinterpret_cast<PyCFunction>(proxyIceConnectionCached), METH_VARARGS, + PyDoc_STR(STRCAST("ice_connectionCached(bool) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getEndpointSelection"), reinterpret_cast<PyCFunction>(proxyIceGetEndpointSelection), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getEndpointSelection() -> bool")) }, + { STRCAST("ice_endpointSelection"), reinterpret_cast<PyCFunction>(proxyIceEndpointSelection), METH_VARARGS, + PyDoc_STR(STRCAST("ice_endpointSelection(Ice.EndpointSelectionType) -> Ice.ObjectPrx")) }, + { STRCAST("ice_isSecure"), reinterpret_cast<PyCFunction>(proxyIceIsSecure), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isSecure() -> bool")) }, + { STRCAST("ice_secure"), reinterpret_cast<PyCFunction>(proxyIceSecure), METH_VARARGS, + PyDoc_STR(STRCAST("ice_secure(bool) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getEncodingVersion"), reinterpret_cast<PyCFunction>(proxyIceGetEncodingVersion), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getEncodingVersion() -> Ice.EncodingVersion")) }, + { STRCAST("ice_encodingVersion"), reinterpret_cast<PyCFunction>(proxyIceEncodingVersion), METH_VARARGS, + PyDoc_STR(STRCAST("ice_endpointSelection(Ice.EncodingVersion) -> Ice.ObjectPrx")) }, + { STRCAST("ice_isPreferSecure"), reinterpret_cast<PyCFunction>(proxyIceIsPreferSecure), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isPreferSecure() -> bool")) }, + { STRCAST("ice_preferSecure"), reinterpret_cast<PyCFunction>(proxyIcePreferSecure), METH_VARARGS, + PyDoc_STR(STRCAST("ice_preferSecure(bool) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getRouter"), reinterpret_cast<PyCFunction>(proxyIceGetRouter), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getRouter() -> Ice.RouterPrx")) }, + { STRCAST("ice_router"), reinterpret_cast<PyCFunction>(proxyIceRouter), METH_VARARGS, + PyDoc_STR(STRCAST("ice_router(Ice.RouterPrx) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getLocator"), reinterpret_cast<PyCFunction>(proxyIceGetLocator), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getLocator() -> Ice.LocatorPrx")) }, + { STRCAST("ice_locator"), reinterpret_cast<PyCFunction>(proxyIceLocator), METH_VARARGS, + PyDoc_STR(STRCAST("ice_locator(Ice.LocatorPrx) -> Ice.ObjectPrx")) }, + { STRCAST("ice_twoway"), reinterpret_cast<PyCFunction>(proxyIceTwoway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_twoway() -> Ice.ObjectPrx")) }, + { STRCAST("ice_isTwoway"), reinterpret_cast<PyCFunction>(proxyIceIsTwoway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isTwoway() -> bool")) }, + { STRCAST("ice_oneway"), reinterpret_cast<PyCFunction>(proxyIceOneway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_oneway() -> Ice.ObjectPrx")) }, + { STRCAST("ice_isOneway"), reinterpret_cast<PyCFunction>(proxyIceIsOneway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isOneway() -> bool")) }, + { STRCAST("ice_batchOneway"), reinterpret_cast<PyCFunction>(proxyIceBatchOneway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_batchOneway() -> Ice.ObjectPrx")) }, + { STRCAST("ice_isBatchOneway"), reinterpret_cast<PyCFunction>(proxyIceIsBatchOneway), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isBatchOneway() -> bool")) }, + { STRCAST("ice_datagram"), reinterpret_cast<PyCFunction>(proxyIceDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("ice_datagram() -> Ice.ObjectPrx")) }, + { STRCAST("ice_isDatagram"), reinterpret_cast<PyCFunction>(proxyIceIsDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isDatagram() -> bool")) }, + { STRCAST("ice_batchDatagram"), reinterpret_cast<PyCFunction>(proxyIceBatchDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("ice_batchDatagram() -> Ice.ObjectPrx")) }, + { STRCAST("ice_isBatchDatagram"), reinterpret_cast<PyCFunction>(proxyIceIsBatchDatagram), METH_NOARGS, + PyDoc_STR(STRCAST("ice_isBatchDatagram() -> bool")) }, + { STRCAST("ice_compress"), reinterpret_cast<PyCFunction>(proxyIceCompress), METH_VARARGS, + PyDoc_STR(STRCAST("ice_compress(bool) -> Ice.ObjectPrx")) }, + { STRCAST("ice_timeout"), reinterpret_cast<PyCFunction>(proxyIceTimeout), METH_VARARGS, + PyDoc_STR(STRCAST("ice_timeout(int) -> Ice.ObjectPrx")) }, + { STRCAST("ice_connectionId"), reinterpret_cast<PyCFunction>(proxyIceConnectionId), METH_VARARGS, + PyDoc_STR(STRCAST("ice_connectionId(string) -> Ice.ObjectPrx")) }, + { STRCAST("ice_getConnection"), reinterpret_cast<PyCFunction>(proxyIceGetConnection), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getConnection() -> Ice.Connection")) }, + { STRCAST("begin_ice_getConnection"), reinterpret_cast<PyCFunction>(proxyBeginIceGetConnection), + METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_ice_getConnection([_response][, _ex]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_getConnection"), reinterpret_cast<PyCFunction>(proxyEndIceGetConnection), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_getConnection(Ice.AsyncResult) -> Ice.Connection")) }, + { STRCAST("ice_getCachedConnection"), reinterpret_cast<PyCFunction>(proxyIceGetCachedConnection), METH_NOARGS, + PyDoc_STR(STRCAST("ice_getCachedConnection() -> Ice.Connection")) }, + { STRCAST("ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyIceFlushBatchRequests), METH_NOARGS, + PyDoc_STR(STRCAST("ice_flushBatchRequests() -> void")) }, + { STRCAST("begin_ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyBeginIceFlushBatchRequests), + METH_VARARGS | METH_KEYWORDS, PyDoc_STR(STRCAST("begin_ice_flushBatchRequests([_ex][, _sent]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_flushBatchRequests"), reinterpret_cast<PyCFunction>(proxyEndIceFlushBatchRequests), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_flushBatchRequests(Ice.AsyncResult) -> void")) }, + { STRCAST("ice_invoke"), reinterpret_cast<PyCFunction>(proxyIceInvoke), METH_VARARGS, + PyDoc_STR(STRCAST("ice_invoke(operation, mode, inParams) -> bool, outParams")) }, + { STRCAST("begin_ice_invoke"), reinterpret_cast<PyCFunction>(proxyBeginIceInvoke), METH_VARARGS | METH_KEYWORDS, + PyDoc_STR(STRCAST("begin_ice_invoke(op, mode, inParams[, _response][, _ex][, _sent][, _ctx]) -> Ice.AsyncResult")) }, + { STRCAST("end_ice_invoke"), reinterpret_cast<PyCFunction>(proxyEndIceInvoke), METH_VARARGS, + PyDoc_STR(STRCAST("end_ice_invoke(Ice.AsyncResult) -> (bool, results)")) }, + { STRCAST("ice_checkedCast"), reinterpret_cast<PyCFunction>(proxyIceCheckedCast), METH_VARARGS | METH_CLASS, + PyDoc_STR(STRCAST("ice_checkedCast(proxy, id[, facetOrCtx[, ctx]]) -> proxy")) }, + { STRCAST("ice_uncheckedCast"), reinterpret_cast<PyCFunction>(proxyIceUncheckedCast), METH_VARARGS | METH_CLASS, + PyDoc_STR(STRCAST("ice_uncheckedCast(proxy) -> proxy")) }, + { STRCAST("checkedCast"), reinterpret_cast<PyCFunction>(proxyCheckedCast), METH_VARARGS | METH_STATIC, + PyDoc_STR(STRCAST("checkedCast(proxy) -> proxy")) }, + { STRCAST("uncheckedCast"), reinterpret_cast<PyCFunction>(proxyUncheckedCast), METH_VARARGS | METH_STATIC, + PyDoc_STR(STRCAST("uncheckedCast(proxy) -> proxy")) }, + { STRCAST("ice_staticId"), reinterpret_cast<PyCFunction>(proxyIceStaticId), METH_NOARGS | METH_STATIC, + PyDoc_STR(STRCAST("ice_staticId() -> string")) }, + { 0, 0 } /* sentinel */ +}; + +namespace IcePy +{ + +PyTypeObject ProxyType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.ObjectPrx"), /* tp_name */ + sizeof(ProxyObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(proxyDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + reinterpret_cast<reprfunc>(proxyRepr), /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + reinterpret_cast<hashfunc>(proxyHash), /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ +#if PY_VERSION_HEX >= 0x03000000 + Py_TPFLAGS_BASETYPE, /* tp_flags */ +#else + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_RICHCOMPARE | + Py_TPFLAGS_HAVE_CLASS, /* tp_flags */ +#endif + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + reinterpret_cast<richcmpfunc>(proxyCompare), /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + ProxyMethods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(proxyNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +} + +bool +IcePy::initProxy(PyObject* module) +{ + if(PyType_Ready(&ProxyType) < 0) + { + return false; + } + PyTypeObject* proxyType = &ProxyType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ObjectPrx"), reinterpret_cast<PyObject*>(proxyType)) < 0) + { + return false; + } + + return true; +} + +PyObject* +IcePy::createProxy(const Ice::ObjectPrx& proxy, const Ice::CommunicatorPtr& communicator, PyObject* type) +{ + assert(proxy); + + if(!type) + { + PyTypeObject* proxyType = &ProxyType; // Necessary to prevent GCC's strict-alias warnings. + type = reinterpret_cast<PyObject*>(proxyType); + } + return reinterpret_cast<PyObject*>(allocateProxy(proxy, communicator, type)); +} + +bool +IcePy::checkProxy(PyObject* p) +{ + PyTypeObject* type = &ProxyType; // Necessary to prevent GCC's strict-alias warnings. + return PyObject_IsInstance(p, reinterpret_cast<PyObject*>(type)) == 1; +} + +Ice::ObjectPrx +IcePy::getProxy(PyObject* p) +{ + assert(checkProxy(p)); + ProxyObject* obj = reinterpret_cast<ProxyObject*>(p); + return *obj->proxy; +} + +bool +IcePy::getProxyArg(PyObject* p, const string& func, const string& arg, Ice::ObjectPrx& proxy, const string& type) +{ + bool result = true; + + if(checkProxy(p)) + { + if(!type.empty()) + { + PyObject* proxyType = lookupType(type); + assert(proxyType); + if(!PyObject_IsInstance(p, proxyType)) + { + result = false; + } + } + } + else if(p != Py_None) + { + result = false; + } + + if(result) + { + if(p != Py_None) + { + ProxyObject* obj = reinterpret_cast<ProxyObject*>(p); + proxy = *obj->proxy; + } + else + { + proxy = 0; + } + } + else + { + string typeName = type.empty() ? "Ice.ObjectPrx" : type; + PyErr_Format(PyExc_ValueError, STRCAST("%s expects a proxy of type %s or None for argument '%s'"), + func.c_str(), typeName.c_str(), arg.c_str()); + } + + return result; +} + +Ice::CommunicatorPtr +IcePy::getProxyCommunicator(PyObject* p) +{ + assert(checkProxy(p)); + ProxyObject* obj = reinterpret_cast<ProxyObject*>(p); + return *obj->communicator; +} diff --git a/python/modules/IcePy/Proxy.h b/python/modules/IcePy/Proxy.h new file mode 100644 index 00000000000..d648886fd99 --- /dev/null +++ b/python/modules/IcePy/Proxy.h @@ -0,0 +1,53 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_PROXY_H +#define ICEPY_PROXY_H + +#include <Config.h> +#include <Ice/ProxyF.h> +#include <Ice/CommunicatorF.h> + +namespace IcePy +{ + +extern PyTypeObject ProxyType; + +bool initProxy(PyObject*); + +PyObject* createProxy(const Ice::ObjectPrx&, const Ice::CommunicatorPtr&, PyObject* = 0); + +// +// Verifies that the given Python object is a proxy. A value of None is not considered legal here. +// +bool checkProxy(PyObject*); + +// +// Extracts a proxy from the given Python object. The Python object *must* be a proxy. +// None is not legal here. +// +Ice::ObjectPrx getProxy(PyObject*); + +// +// Extracts a proxy argument from the given Python object. None is accepted here. If the Python +// object contains an invalid value, the function raises a ValueError exception and returns +// false. The optional trailing string provides the Python class name of a derived Slice +// interface that the caller requires. +// +bool getProxyArg(PyObject*, const std::string&, const std::string&, Ice::ObjectPrx&, + const std::string& = std::string()); + +// +// Gets the communicator associated with the proxy object. +// +Ice::CommunicatorPtr getProxyCommunicator(PyObject*); + +} + +#endif diff --git a/python/modules/IcePy/Slice.cpp b/python/modules/IcePy/Slice.cpp new file mode 100644 index 00000000000..9adccc5e4c3 --- /dev/null +++ b/python/modules/IcePy/Slice.cpp @@ -0,0 +1,259 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Slice.h> +#include <Util.h> +#include <Slice/Preprocessor.h> +#include <Slice/PythonUtil.h> +#include <Slice/Util.h> +#include <IceUtil/Options.h> + +// +// Python headers needed for PyEval_EvalCode. +// +#include <compile.h> +#include <eval.h> + +using namespace std; +using namespace IcePy; +using namespace Slice; +using namespace Slice::Python; + +extern "C" +PyObject* +IcePy_loadSlice(PyObject* /*self*/, PyObject* args) +{ + char* cmd; + PyObject* list = 0; + if(!PyArg_ParseTuple(args, STRCAST("s|O!"), &cmd, &PyList_Type, &list)) + { + return 0; + } + + vector<string> argSeq; + try + { + argSeq = IceUtilInternal::Options::split(cmd); + } + catch(const IceUtilInternal::BadOptException& ex) + { + PyErr_Format(PyExc_RuntimeError, "error in Slice options: %s", ex.reason.c_str()); + return 0; + } + catch(const IceUtilInternal::APIException& ex) + { + PyErr_Format(PyExc_RuntimeError, "error in Slice options: %s", ex.reason.c_str()); + return 0; + } + + if(list) + { + if(!listToStringSeq(list, argSeq)) + { + return 0; + } + } + + IceUtilInternal::Options opts; + opts.addOpt("D", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("U", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat); + opts.addOpt("d", "debug"); + opts.addOpt("", "ice"); + opts.addOpt("", "underscore"); + opts.addOpt("", "checksum"); + opts.addOpt("", "all"); + + vector<string> files; + try + { + argSeq.insert(argSeq.begin(), ""); // dummy argv[0] + files = opts.parse(argSeq); + if(files.empty()) + { + PyErr_Format(PyExc_RuntimeError, "no Slice files specified in `%s'", cmd); + return 0; + } + } + catch(const IceUtilInternal::BadOptException& ex) + { + PyErr_Format(PyExc_RuntimeError, "error in Slice options: %s", ex.reason.c_str()); + return 0; + } + catch(const IceUtilInternal::APIException& ex) + { + PyErr_Format(PyExc_RuntimeError, "error in Slice options: %s", ex.reason.c_str()); + return 0; + } + + vector<string> cppArgs; + Ice::StringSeq includePaths; + bool debug = false; + bool ice = true; // This must be true so that we can create Ice::Identity when necessary. + bool underscore = opts.isSet("underscore"); + bool all = false; + bool checksum = false; + if(opts.isSet("D")) + { + vector<string> optargs = opts.argVec("D"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-D" + *i); + } + } + if(opts.isSet("U")) + { + vector<string> optargs = opts.argVec("U"); + for(vector<string>::const_iterator i = optargs.begin(); i != optargs.end(); ++i) + { + cppArgs.push_back("-U" + *i); + } + } + if(opts.isSet("I")) + { + includePaths = opts.argVec("I"); + for(vector<string>::const_iterator i = includePaths.begin(); i != includePaths.end(); ++i) + { + cppArgs.push_back("-I" + *i); + } + } + debug = opts.isSet("d") || opts.isSet("debug"); + all = opts.isSet("all"); + checksum = opts.isSet("checksum"); + + bool ignoreRedefs = false; + bool keepComments = true; + + for(vector<string>::const_iterator p = files.begin(); p != files.end(); ++p) + { + string file = *p; + Slice::PreprocessorPtr icecpp = Slice::Preprocessor::create("icecpp", file, cppArgs); + FILE* cppHandle = icecpp->preprocess(keepComments, "-D__SLICE2PY__"); + + if(cppHandle == 0) + { + PyErr_Format(PyExc_RuntimeError, "Slice preprocessing failed for `%s'", cmd); + return 0; + } + + UnitPtr u = Slice::Unit::createUnit(ignoreRedefs, all, ice, underscore); + int parseStatus = u->parse(file, cppHandle, debug); + + if(!icecpp->close() || parseStatus == EXIT_FAILURE) + { + PyErr_Format(PyExc_RuntimeError, "Slice parsing failed for `%s'", cmd); + u->destroy(); + return 0; + } + + // + // Generate the Python code into a string stream. + // + ostringstream codeStream; + IceUtilInternal::Output out(codeStream); + out.setUseTab(false); + generate(u, all, checksum, includePaths, out); + u->destroy(); + + string code = codeStream.str(); + + // + // We need to invoke Ice.updateModules() so that all of the types we've just generated + // are made "public". + // + code += "\nIce.updateModules()\n"; + + PyObjectHandle src = Py_CompileString(const_cast<char*>(code.c_str()), const_cast<char*>(file.c_str()), + Py_file_input); + if(!src.get()) + { + return 0; + } + + PyObjectHandle globals = PyDict_New(); + if(!globals.get()) + { + return 0; + } + PyDict_SetItemString(globals.get(), "__builtins__", PyEval_GetBuiltins()); + +#if PY_VERSION_HEX >= 0x03000000 + PyObjectHandle val = PyEval_EvalCode(src.get(), globals.get(), 0); +#else + PyObjectHandle val = PyEval_EvalCode(reinterpret_cast<PyCodeObject*>(src.get()), globals.get(), 0); +#endif + if(!val.get()) + { + return 0; + } + } + + Py_INCREF(Py_None); + return Py_None; +} + +extern "C" +PyObject* +IcePy_compile(PyObject* /*self*/, PyObject* args) +{ + PyObject* list = 0; + if(!PyArg_ParseTuple(args, STRCAST("O!"), &PyList_Type, &list)) + { + return 0; + } + + vector<string> argSeq; + if(list) + { + if(!listToStringSeq(list, argSeq)) + { + return 0; + } + } + + char** argv = new char*[argSeq.size()]; + for(size_t i = 0; i < argSeq.size(); ++i) + { + argv[i] = const_cast<char*>(argSeq[i].c_str()); + } + + int rc; + try + { + rc = Slice::Python::compile(static_cast<int>(argSeq.size()), argv); + } + catch(const std::exception& ex) + { + getErrorStream() << argv[0] << ": error:" << ex.what() << endl; + rc = EXIT_FAILURE; + } + catch(const std::string& msg) + { + getErrorStream() << argv[0] << ": error:" << msg << endl; + rc = EXIT_FAILURE; + } + catch(const char* msg) + { + getErrorStream() << argv[0] << ": error:" << msg << endl; + rc = EXIT_FAILURE; + } + catch(...) + { + getErrorStream() << argv[0] << ": error:" << "unknown exception" << endl; + rc = EXIT_FAILURE; + } + + delete[] argv; + + // PyInt_FromLong doesn't exist in python 3. + return PyLong_FromLong(rc); +} diff --git a/python/modules/IcePy/Slice.h b/python/modules/IcePy/Slice.h new file mode 100644 index 00000000000..4d142906d66 --- /dev/null +++ b/python/modules/IcePy/Slice.h @@ -0,0 +1,18 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_SLICE_H +#define ICEPY_SLICE_H + +#include <Config.h> + +extern "C" PyObject* IcePy_loadSlice(PyObject*, PyObject*); +extern "C" PyObject* IcePy_compile(PyObject*, PyObject*); + +#endif diff --git a/python/modules/IcePy/Thread.cpp b/python/modules/IcePy/Thread.cpp new file mode 100644 index 00000000000..379b7556e47 --- /dev/null +++ b/python/modules/IcePy/Thread.cpp @@ -0,0 +1,72 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Thread.h> + +using namespace std; +using namespace IcePy; + +IcePy::AllowThreads::AllowThreads() +{ + _state = PyEval_SaveThread(); +} + +IcePy::AllowThreads::~AllowThreads() +{ + PyEval_RestoreThread(_state); +} + +IcePy::AdoptThread::AdoptThread() +{ + _state = PyGILState_Ensure(); +} + +IcePy::AdoptThread::~AdoptThread() +{ + PyGILState_Release(_state); +} + +IcePy::ThreadHook::ThreadHook(PyObject* threadNotification) : + _threadNotification(threadNotification) +{ + Py_INCREF(threadNotification); +} + +void +IcePy::ThreadHook::start() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_threadNotification.get(), STRCAST("start"), 0); + if(!tmp.get()) + { + throwPythonException(); + } +} + +void +IcePy::ThreadHook::stop() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + PyObjectHandle tmp = PyObject_CallMethod(_threadNotification.get(), STRCAST("stop"), 0); + if(!tmp.get()) + { + throwPythonException(); + } +} + +PyObject* +IcePy::ThreadHook::getObject() +{ + return _threadNotification.get(); +} diff --git a/python/modules/IcePy/Thread.h b/python/modules/IcePy/Thread.h new file mode 100644 index 00000000000..8b84bd5c40e --- /dev/null +++ b/python/modules/IcePy/Thread.h @@ -0,0 +1,125 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_THREAD_H +#define ICEPY_THREAD_H + +#include <Config.h> +#include <Util.h> +#include <Ice/Initialize.h> +#include <IceUtil/Thread.h> +#include <IceUtil/Monitor.h> + +namespace IcePy +{ + +// +// Release Python's Global Interpreter Lock during potentially time-consuming +// (and non-Python related) work. +// +class AllowThreads +{ +public: + + AllowThreads(); + ~AllowThreads(); + +private: + + PyThreadState* _state; +}; + +// +// Ensure that the current thread is capable of calling into Python. +// +class AdoptThread +{ +public: + + AdoptThread(); + ~AdoptThread(); + +private: + + PyGILState_STATE _state; +}; + +// +// ThreadHook ensures that every Ice thread is ready to invoke the Python API. +// It also acts as a wrapper for an optional ThreadNotification object. +// +class ThreadHook : public Ice::ThreadNotification +{ +public: + + ThreadHook(PyObject*); + + virtual void start(); + virtual void stop(); + + PyObject* getObject(); + +private: + + PyObjectHandle _threadNotification; +}; +typedef IceUtil::Handle<ThreadHook> ThreadHookPtr; + +// +// This class invokes a member function in a separate thread. +// +template<typename T> +class InvokeThread : public IceUtil::Thread +{ +public: + + InvokeThread(const IceInternal::Handle<T>& target, void (T::*func)(void), + IceUtil::Monitor<IceUtil::Mutex>& monitor, bool& done) : + _target(target), _func(func), _monitor(monitor), _done(done), _ex(0) + { + } + + ~InvokeThread() + { + delete _ex; + } + + virtual void run() + { + try + { + (_target.get() ->* _func)(); + } + catch(const Ice::Exception& ex) + { + _ex = ex.ice_clone(); + } + + IceUtil::Monitor<IceUtil::Mutex>::Lock sync(_monitor); + _done = true; + _monitor.notify(); + } + + Ice::Exception* getException() const + { + return _ex; + } + +private: + + IceInternal::Handle<T> _target; + void (T::*_func)(void); + IceUtil::Monitor<IceUtil::Mutex>& _monitor; + bool& _done; + Ice::Exception* _ex; +}; + +} + +#endif diff --git a/python/modules/IcePy/Types.cpp b/python/modules/IcePy/Types.cpp new file mode 100644 index 00000000000..ed737247264 --- /dev/null +++ b/python/modules/IcePy/Types.cpp @@ -0,0 +1,4436 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Types.h> +#include <Current.h> +#include <Proxy.h> +#include <Thread.h> +#include <Util.h> +#include <IceUtil/InputUtil.h> +#include <IceUtil/ScopedArray.h> +#include <Ice/LocalException.h> +#include <Ice/SlicedData.h> + +#include <list> +#include <limits> + +using namespace std; +using namespace IcePy; +using namespace IceUtil; +using namespace IceUtilInternal; + +typedef map<string, ClassInfoPtr> ClassInfoMap; +static ClassInfoMap _classInfoMap; + +typedef map<Ice::Int, ClassInfoPtr> CompactIdMap; +static CompactIdMap _compactIdMap; + +typedef map<string, ProxyInfoPtr> ProxyInfoMap; +static ProxyInfoMap _proxyInfoMap; + +typedef map<string, ExceptionInfoPtr> ExceptionInfoMap; +static ExceptionInfoMap _exceptionInfoMap; + +namespace IcePy +{ + +class InfoMapDestroyer +{ +public: + + ~InfoMapDestroyer(); +}; +static InfoMapDestroyer infoMapDestroyer; + +class ReadObjectCallback : public Ice::ReadObjectCallback +{ +public: + + ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, PyObject*, void*); + ~ReadObjectCallback(); + + virtual void invoke(const ::Ice::ObjectPtr&); + +private: + + ClassInfoPtr _info; + UnmarshalCallbackPtr _cb; + PyObject* _target; + void* _closure; +}; + +struct TypeInfoObject +{ + PyObject_HEAD + IcePy::TypeInfoPtr* info; +}; + +struct ExceptionInfoObject +{ + PyObject_HEAD + IcePy::ExceptionInfoPtr* info; +}; + +extern PyTypeObject TypeInfoType; +extern PyTypeObject ExceptionInfoType; + +bool +writeString(PyObject* p, const Ice::OutputStreamPtr& os) +{ + if(p == Py_None) + { + os->write(string()); + } + else if(checkString(p)) + { + os->write(getString(p)); + } +#if defined(Py_USING_UNICODE) && PY_VERSION_HEX < 0x03000000 + else if(PyUnicode_Check(p)) + { + // + // Convert a Unicode object to a UTF-8 string and write it without manipulation from + // a C++ string converter. + // + PyObjectHandle h = PyUnicode_AsUTF8String(p); + if(!h.get()) + { + return false; + } + os->write(getString(h.get()), false); + } +#endif + else + { + assert(false); + } + + return true; +} + +} + +#ifdef WIN32 +extern "C" +#endif +static TypeInfoObject* +typeInfoNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + TypeInfoObject* self = reinterpret_cast<TypeInfoObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->info = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +typeInfoDealloc(TypeInfoObject* self) +{ + delete self->info; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static ExceptionInfoObject* +exceptionInfoNew(PyTypeObject* type, PyObject* /*args*/, PyObject* /*kwds*/) +{ + ExceptionInfoObject* self = reinterpret_cast<ExceptionInfoObject*>(type->tp_alloc(type, 0)); + if(!self) + { + return 0; + } + self->info = 0; + return self; +} + +#ifdef WIN32 +extern "C" +#endif +static void +exceptionInfoDealloc(ExceptionInfoObject* self) +{ + delete self->info; + Py_TYPE(self)->tp_free(reinterpret_cast<PyObject*>(self)); +} + +#ifdef WIN32 +extern "C" +#endif +static void +unsetDealloc(PyTypeObject* /*self*/) +{ + Py_FatalError("deallocating Unset"); +} + +#ifdef WIN32 +extern "C" +#endif +static int +unsetNonzero(PyObject* /*v*/) +{ + // + // We define tp_as_number->nb_nonzero so that the Unset marker value evaluates as "zero" or "false". + // + return 0; +} + +#ifdef WIN32 +extern "C" +#endif +static PyObject* +unsetRepr(PyObject* /*v*/) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyBytes_FromString("Unset"); +#else + return PyString_FromString("Unset"); +#endif +} + +// +// addClassInfo() +// +static void +addClassInfo(const string& id, const ClassInfoPtr& info) +{ + // + // Do not assert. An application may load statically- + // translated definitions and then dynamically load + // duplicate definitions. + // +// assert(_classInfoMap.find(id) == _classInfoMap.end()); + ClassInfoMap::iterator p = _classInfoMap.find(id); + if(p != _classInfoMap.end()) + { + _classInfoMap.erase(p); + } + _classInfoMap.insert(ClassInfoMap::value_type(id, info)); +} + +// +// addProxyInfo() +// +static void +addProxyInfo(const string& id, const ProxyInfoPtr& info) +{ + // + // Do not assert. An application may load statically- + // translated definitions and then dynamically load + // duplicate definitions. + // +// assert(_proxyInfoMap.find(id) == _proxyInfoMap.end()); + ProxyInfoMap::iterator p = _proxyInfoMap.find(id); + if(p != _proxyInfoMap.end()) + { + _proxyInfoMap.erase(p); + } + _proxyInfoMap.insert(ProxyInfoMap::value_type(id, info)); +} + +// +// lookupProxyInfo() +// +static IcePy::ProxyInfoPtr +lookupProxyInfo(const string& id) +{ + ProxyInfoMap::iterator p = _proxyInfoMap.find(id); + if(p != _proxyInfoMap.end()) + { + return p->second; + } + return 0; +} + +// +// addExceptionInfo() +// +static void +addExceptionInfo(const string& id, const ExceptionInfoPtr& info) +{ + // + // Do not assert. An application may load statically- + // translated definitions and then dynamically load + // duplicate definitions. + // +// assert(_exceptionInfoMap.find(id) == _exceptionInfoMap.end()); + _exceptionInfoMap.insert(ExceptionInfoMap::value_type(id, info)); +} + +// +// SlicedDataUtil implementation +// +PyObject* IcePy::SlicedDataUtil::_slicedDataType = 0; +PyObject* IcePy::SlicedDataUtil::_sliceInfoType = 0; + +IcePy::SlicedDataUtil::SlicedDataUtil() +{ +} + +IcePy::SlicedDataUtil::~SlicedDataUtil() +{ + // + // Make sure we break any cycles among the ObjectReaders in preserved slices. + // + for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p) + { + Ice::SlicedDataPtr slicedData = (*p)->getSlicedData(); + for(Ice::SliceInfoSeq::const_iterator q = slicedData->slices.begin(); q != slicedData->slices.end(); ++q) + { + // + // Don't just call (*q)->objects.clear(), as releasing references + // to the objects could have unexpected side effects. We exchange + // the vector into a temporary and then let the temporary fall out + // of scope. + // + vector<Ice::ObjectPtr> tmp; + tmp.swap((*q)->objects); + } + } +} + +void +IcePy::SlicedDataUtil::add(const ObjectReaderPtr& reader) +{ + assert(reader->getSlicedData()); + _readers.insert(reader); +} + +void +IcePy::SlicedDataUtil::update() +{ + for(set<ObjectReaderPtr>::iterator p = _readers.begin(); p != _readers.end(); ++p) + { + setMember((*p)->getObject(), (*p)->getSlicedData()); + } +} + +void +IcePy::SlicedDataUtil::setMember(PyObject* obj, const Ice::SlicedDataPtr& slicedData) +{ + // + // Create a Python equivalent of the SlicedData object. + // + + assert(slicedData); + + if(!_slicedDataType) + { + _slicedDataType = lookupType("Ice.SlicedData"); + assert(_slicedDataType); + } + if(!_sliceInfoType) + { + _sliceInfoType = lookupType("Ice.SliceInfo"); + assert(_sliceInfoType); + } + + IcePy::PyObjectHandle args = PyTuple_New(0); + if(!args.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + PyObjectHandle sd = PyEval_CallObject(_slicedDataType, args.get()); + if(!sd.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + PyObjectHandle slices = PyTuple_New(slicedData->slices.size()); + if(!slices.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + if(PyObject_SetAttrString(sd.get(), STRCAST("slices"), slices.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // Translate each SliceInfo object into its Python equivalent. + // + int i = 0; + for(vector<Ice::SliceInfoPtr>::const_iterator p = slicedData->slices.begin(); p != slicedData->slices.end(); ++p) + { + PyObjectHandle slice = PyEval_CallObject(_sliceInfoType, args.get()); + if(!slice.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + PyTuple_SET_ITEM(slices.get(), i++, slice.get()); + Py_INCREF(slice.get()); // PyTuple_SET_ITEM steals a reference. + + // + // typeId + // + PyObjectHandle typeId = createString((*p)->typeId); + if(!typeId.get() || PyObject_SetAttrString(slice.get(), STRCAST("typeId"), typeId.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // compactId + // + PyObjectHandle compactId = PyLong_FromLong((*p)->compactId); + if(!compactId.get() || PyObject_SetAttrString(slice.get(), STRCAST("compactId"), compactId.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // bytes + // +#if PY_VERSION_HEX >= 0x03000000 + PyObjectHandle bytes = + PyBytes_FromStringAndSize(reinterpret_cast<const char*>(&(*p)->bytes[0]), (*p)->bytes.size()); +#else + PyObjectHandle bytes = + PyString_FromStringAndSize(reinterpret_cast<const char*>(&(*p)->bytes[0]), (*p)->bytes.size()); +#endif + if(!bytes.get() || PyObject_SetAttrString(slice.get(), STRCAST("bytes"), bytes.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // objects + // + PyObjectHandle objects = PyTuple_New((*p)->objects.size()); + if(!objects.get() || PyObject_SetAttrString(slice.get(), STRCAST("objects"), objects.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + int j = 0; + for(vector<Ice::ObjectPtr>::iterator q = (*p)->objects.begin(); q != (*p)->objects.end(); ++q) + { + // + // Each element in the objects list is an instance of ObjectReader that wraps a Python object. + // + assert(*q); + ObjectReaderPtr r = ObjectReaderPtr::dynamicCast(*q); + assert(r); + PyObject* obj = r->getObject(); + assert(obj != Py_None); // Should be non-nil. + PyTuple_SET_ITEM(objects.get(), j++, obj); + Py_INCREF(obj); // PyTuple_SET_ITEM steals a reference. + } + + // + // hasOptionalMembers + // + PyObject* hasOptionalMembers = (*p)->hasOptionalMembers ? getTrue() : getFalse(); + if(PyObject_SetAttrString(slice.get(), STRCAST("hasOptionalMembers"), hasOptionalMembers) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // isLastSlice + // + PyObject* isLastSlice = (*p)->isLastSlice ? getTrue() : getFalse(); + if(PyObject_SetAttrString(slice.get(), STRCAST("isLastSlice"), isLastSlice) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + + if(PyObject_SetAttrString(obj, STRCAST("_ice_slicedData"), sd.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } +} + +// +// Instances of preserved class and exception types may have a data member +// named _ice_slicedData which is an instance of the Python class Ice.SlicedData. +// +Ice::SlicedDataPtr +IcePy::SlicedDataUtil::getMember(PyObject* obj, ObjectMap* objectMap) +{ + Ice::SlicedDataPtr slicedData; + + if(PyObject_HasAttrString(obj, STRCAST("_ice_slicedData"))) + { + PyObjectHandle sd = PyObject_GetAttrString(obj, STRCAST("_ice_slicedData")); + assert(sd.get()); + + if(sd.get() != Py_None) + { + // + // The "slices" member is a tuple of Ice.SliceInfo objects. + // + PyObjectHandle sl = PyObject_GetAttrString(sd.get(), STRCAST("slices")); + assert(sl.get()); + assert(PyTuple_Check(sl.get())); + + Ice::SliceInfoSeq slices; + + Py_ssize_t sz = PyTuple_GET_SIZE(sl.get()); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObjectHandle s = PyTuple_GET_ITEM(sl.get(), i); + Py_INCREF(s.get()); + + Ice::SliceInfoPtr info = new Ice::SliceInfo; + + PyObjectHandle typeId = PyObject_GetAttrString(s.get(), STRCAST("typeId")); + assert(typeId.get()); + info->typeId = getString(typeId.get()); + + PyObjectHandle compactId = PyObject_GetAttrString(s.get(), STRCAST("compactId")); + assert(compactId.get()); + info->compactId = static_cast<int>(PyLong_AsLong(compactId.get())); + + PyObjectHandle bytes = PyObject_GetAttrString(s.get(), STRCAST("bytes")); + assert(bytes.get()); + char* str; + Py_ssize_t strsz; +#if PY_VERSION_HEX >= 0x03000000 + assert(PyBytes_Check(bytes.get())); + PyBytes_AsStringAndSize(bytes.get(), &str, &strsz); +#else + assert(PyString_Check(bytes.get())); + PyString_AsStringAndSize(bytes.get(), &str, &strsz); +#endif + vector<Ice::Byte> vtmp(reinterpret_cast<Ice::Byte*>(str), reinterpret_cast<Ice::Byte*>(str + strsz)); + info->bytes.swap(vtmp); + + PyObjectHandle objects = PyObject_GetAttrString(s.get(), STRCAST("objects")); + assert(objects.get()); + assert(PyTuple_Check(objects.get())); + Py_ssize_t osz = PyTuple_GET_SIZE(objects.get()); + for(Py_ssize_t j = 0; j < osz; ++j) + { + PyObject* o = PyTuple_GET_ITEM(objects.get(), j); + + Ice::ObjectPtr writer; + + ObjectMap::iterator i = objectMap->find(o); + if(i == objectMap->end()) + { + writer = new ObjectWriter(o, objectMap); + objectMap->insert(ObjectMap::value_type(o, writer)); + } + else + { + writer = i->second; + } + + info->objects.push_back(writer); + } + + PyObjectHandle hasOptionalMembers = PyObject_GetAttrString(s.get(), STRCAST("hasOptionalMembers")); + assert(hasOptionalMembers.get()); + info->hasOptionalMembers = PyObject_IsTrue(hasOptionalMembers.get()) ? true : false; + + PyObjectHandle isLastSlice = PyObject_GetAttrString(s.get(), STRCAST("isLastSlice")); + assert(isLastSlice.get()); + info->isLastSlice = PyObject_IsTrue(isLastSlice.get()) ? true : false; + + slices.push_back(info); + } + + slicedData = new Ice::SlicedData(slices); + } + } + + return slicedData; +} + +// +// UnmarshalCallback implementation. +// +IcePy::UnmarshalCallback::~UnmarshalCallback() +{ +} + +// +// TypeInfo implementation. +// +IcePy::TypeInfo::TypeInfo() +{ +} + +bool +IcePy::TypeInfo::usesClasses() const +{ + return false; +} + +void +IcePy::TypeInfo::unmarshaled(PyObject*, PyObject*, void*) +{ + assert(false); +} + +void +IcePy::TypeInfo::destroy() +{ +} + +// +// PrimitiveInfo implementation. +// +IcePy::PrimitiveInfo::PrimitiveInfo(Kind k) : + kind(k) +{ +} + +string +IcePy::PrimitiveInfo::getId() const +{ + switch(kind) + { + case KindBool: + return "bool"; + case KindByte: + return "byte"; + case KindShort: + return "short"; + case KindInt: + return "int"; + case KindLong: + return "long"; + case KindFloat: + return "float"; + case KindDouble: + return "double"; + case KindString: + return "string"; + } + assert(false); + return string(); +} + +bool +IcePy::PrimitiveInfo::validate(PyObject* p) +{ + switch(kind) + { + case PrimitiveInfo::KindBool: + { + int isTrue = PyObject_IsTrue(p); + if(isTrue < 0) + { + return false; + } + break; + } + case PrimitiveInfo::KindByte: + { + long val = PyLong_AsLong(p); + + if(PyErr_Occurred() || val < 0 || val > 255) + { + return false; + } + break; + } + case PrimitiveInfo::KindShort: + { + long val = PyLong_AsLong(p); + + if(PyErr_Occurred() || val < SHRT_MIN || val > SHRT_MAX) + { + return false; + } + break; + } + case PrimitiveInfo::KindInt: + { + long val = PyLong_AsLong(p); + + if(PyErr_Occurred() || val < INT_MIN || val > INT_MAX) + { + return false; + } + break; + } + case PrimitiveInfo::KindLong: + { + PyLong_AsLongLong(p); // Just to see if it raises an error. + + if(PyErr_Occurred()) + { + return false; + } + + break; + } + case PrimitiveInfo::KindFloat: + { + if(!PyFloat_Check(p)) + { + if(PyLong_Check(p)) + { + PyLong_AsDouble(p); // Just to see if it raises an error. + if(PyErr_Occurred()) + { + return false; + } + } +#if PY_VERSION_HEX < 0x03000000 + else if(PyInt_Check(p)) + { + return true; + } +#endif + else + { + return false; + } + } + else + { + // Ensure double does not exceed maximum float value before casting + double val = PyFloat_AsDouble(p); + return val <= numeric_limits<float>::max() && val >= -numeric_limits<float>::max(); + } + + break; + } + case PrimitiveInfo::KindDouble: + { + if(!PyFloat_Check(p)) + { + if(PyLong_Check(p)) + { + PyLong_AsDouble(p); // Just to see if it raises an error. + if(PyErr_Occurred()) + { + return false; + } + } +#if PY_VERSION_HEX < 0x03000000 + else if(PyInt_Check(p)) + { + return true; + } +#endif + else + { + return false; + } + } + + break; + } + case PrimitiveInfo::KindString: + { +#if defined(Py_USING_UNICODE) && PY_VERSION_HEX < 0x03000000 + if(p != Py_None && !checkString(p) && !PyUnicode_Check(p)) +#else + if(p != Py_None && !checkString(p)) +#endif + { + return false; + } + break; + } + } + + return true; +} + +bool +IcePy::PrimitiveInfo::variableLength() const +{ + return kind == KindString; +} + +int +IcePy::PrimitiveInfo::wireSize() const +{ + switch(kind) + { + case KindBool: + case KindByte: + return 1; + case KindShort: + return 2; + case KindInt: + return 4; + case KindLong: + return 8; + case KindFloat: + return 4; + case KindDouble: + return 8; + case KindString: + return 1; + } + assert(false); + return 0; +} + +Ice::OptionalFormat +IcePy::PrimitiveInfo::optionalFormat() const +{ + switch(kind) + { + case KindBool: + case KindByte: + return Ice::OptionalFormatF1; + case KindShort: + return Ice::OptionalFormatF2; + case KindInt: + return Ice::OptionalFormatF4; + case KindLong: + return Ice::OptionalFormatF8; + case KindFloat: + return Ice::OptionalFormatF4; + case KindDouble: + return Ice::OptionalFormatF8; + case KindString: + return Ice::OptionalFormatVSize; + } + + assert(false); + return Ice::OptionalFormatF1; +} + +void +IcePy::PrimitiveInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap*, bool, const Ice::StringSeq*) +{ + switch(kind) + { + case PrimitiveInfo::KindBool: + { + int isTrue = PyObject_IsTrue(p); + if(isTrue < 0) + { + assert(false); // validate() should have caught this. + } + os->write(isTrue ? true : false); + break; + } + case PrimitiveInfo::KindByte: + { + long val = PyLong_AsLong(p); + assert(!PyErr_Occurred()); // validate() should have caught this. + assert(val >= 0 && val <= 255); // validate() should have caught this. + os->write(static_cast<Ice::Byte>(val)); + break; + } + case PrimitiveInfo::KindShort: + { + long val = PyLong_AsLong(p); + assert(!PyErr_Occurred()); // validate() should have caught this. + assert(val >= SHRT_MIN && val <= SHRT_MAX); // validate() should have caught this. + os->write(static_cast<Ice::Short>(val)); + break; + } + case PrimitiveInfo::KindInt: + { + long val = PyLong_AsLong(p); + assert(!PyErr_Occurred()); // validate() should have caught this. + assert(val >= INT_MIN && val <= INT_MAX); // validate() should have caught this. + os->write(static_cast<Ice::Int>(val)); + break; + } + case PrimitiveInfo::KindLong: + { + Ice::Long val = PyLong_AsLongLong(p); + assert(!PyErr_Occurred()); // validate() should have caught this. + os->write(val); + break; + } + case PrimitiveInfo::KindFloat: + { + float val = static_cast<float>(PyFloat_AsDouble(p)); // Attempts to perform conversion. + if(PyErr_Occurred()) + { + throw AbortMarshaling(); + } + + os->write(val); + break; + } + case PrimitiveInfo::KindDouble: + { + double val = PyFloat_AsDouble(p); // Attempts to perform conversion. + if(PyErr_Occurred()) + { + throw AbortMarshaling(); + } + + os->write(val); + break; + } + case PrimitiveInfo::KindString: + { + if(!writeString(p, os)) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + break; + } + } +} + +void +IcePy::PrimitiveInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool, const Ice::StringSeq*) +{ + switch(kind) + { + case PrimitiveInfo::KindBool: + { + bool b; + is->read(b); + if(b) + { + cb->unmarshaled(getTrue(), target, closure); + } + else + { + cb->unmarshaled(getFalse(), target, closure); + } + break; + } + case PrimitiveInfo::KindByte: + { + Ice::Byte val; + is->read(val); + PyObjectHandle p = PyLong_FromLong(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindShort: + { + Ice::Short val; + is->read(val); + PyObjectHandle p = PyLong_FromLong(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindInt: + { + Ice::Int val; + is->read(val); + PyObjectHandle p = PyLong_FromLong(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindLong: + { + Ice::Long val; + is->read(val); + PyObjectHandle p = PyLong_FromLongLong(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindFloat: + { + Ice::Float val; + is->read(val); + PyObjectHandle p = PyFloat_FromDouble(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindDouble: + { + Ice::Double val; + is->read(val); + PyObjectHandle p = PyFloat_FromDouble(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + case PrimitiveInfo::KindString: + { + string val; + is->read(val); + PyObjectHandle p = createString(val); + cb->unmarshaled(p.get(), target, closure); + break; + } + } +} + +void +IcePy::PrimitiveInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory*) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << getId() << ">"; + return; + } + PyObjectHandle p = PyObject_Str(value); + if(!p.get()) + { + return; + } + assert(checkString(p.get())); + out << getString(p.get()); +} + +// +// EnumInfo implementation. +// +IcePy::EnumInfo::EnumInfo(const string& ident, PyObject* t, PyObject* e) : + id(ident), pythonType(t), maxValue(0) +{ + assert(PyType_Check(t)); + assert(PyDict_Check(e)); + + Py_INCREF(t); + + Py_ssize_t pos = 0; + PyObject* key; + PyObject* value; + while(PyDict_Next(e, &pos, &key, &value)) + { +#if PY_VERSION_HEX >= 0x03000000 + assert(PyLong_Check(key)); +#else + assert(PyInt_Check(key)); +#endif + const Ice::Int val = static_cast<Ice::Int>(PyLong_AsLong(key)); + assert(enumerators.find(val) == enumerators.end()); + + Py_INCREF(value); + assert(PyObject_IsInstance(value, t)); + const_cast<EnumeratorMap&>(enumerators)[val] = value; + + if(val > maxValue) + { + const_cast<Ice::Int&>(maxValue) = val; + } + } +} + +string +IcePy::EnumInfo::getId() const +{ + return id; +} + +bool +IcePy::EnumInfo::validate(PyObject* val) +{ + return PyObject_IsInstance(val, pythonType.get()) == 1; +} + +bool +IcePy::EnumInfo::variableLength() const +{ + return true; +} + +int +IcePy::EnumInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::EnumInfo::optionalFormat() const +{ + return Ice::OptionalFormatSize; +} + +void +IcePy::EnumInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional, const Ice::StringSeq*) +{ + // + // Validate value. + // + const Ice::Int val = valueForEnumerator(p); + if(val < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + os->writeEnum(val, maxValue); +} + +void +IcePy::EnumInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool, const Ice::StringSeq*) +{ + Ice::Int val = is->readEnum(maxValue); + + PyObjectHandle p = enumeratorForValue(val); + if(!p.get()) + { + ostringstream ostr; + ostr << "enumerator " << val << " is out of range for enum " << id; + setPythonException(Ice::MarshalException(__FILE__, __LINE__, ostr.str())); + throw AbortMarshaling(); + } + + cb->unmarshaled(p.get(), target, closure); +} + +void +IcePy::EnumInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory*) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + PyObjectHandle p = PyObject_Str(value); + if(!p.get()) + { + return; + } + assert(checkString(p.get())); + out << getString(p.get()); +} + +Ice::Int +IcePy::EnumInfo::valueForEnumerator(PyObject* p) const +{ + assert(PyObject_IsInstance(p, pythonType.get()) == 1); + + PyObjectHandle v = PyObject_GetAttrString(p, STRCAST("_value")); + if(!v.get()) + { + assert(PyErr_Occurred()); + return -1; + } +#if PY_VERSION_HEX >= 0x03000000 + if(!PyLong_Check(v.get())) +#else + if(!PyInt_Check(v.get())) +#endif + { + PyErr_Format(PyExc_ValueError, STRCAST("value for enum %s is not an int"), id.c_str()); + return -1; + } + const Ice::Int val = static_cast<Ice::Int>(PyLong_AsLong(v.get())); + if(enumerators.find(val) == enumerators.end()) + { + PyErr_Format(PyExc_ValueError, STRCAST("illegal value %d for enum %s"), val, id.c_str()); + return -1; + } + + return val; +} + +PyObject* +IcePy::EnumInfo::enumeratorForValue(Ice::Int v) const +{ + EnumeratorMap::const_iterator p = enumerators.find(v); + if(p == enumerators.end()) + { + return 0; + } + PyObject* r = p->second.get(); + Py_INCREF(r); + return r; +} + +// +// DataMember implementation. +// +void +IcePy::DataMember::unmarshaled(PyObject* val, PyObject* target, void*) +{ + if(PyObject_SetAttrString(target, const_cast<char*>(name.c_str()), val) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } +} + +static void +convertDataMembers(PyObject* members, DataMemberList& reqMembers, DataMemberList& optMembers, bool allowOptional) +{ + list<DataMemberPtr> optList; + + Py_ssize_t sz = PyTuple_GET_SIZE(members); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* m = PyTuple_GET_ITEM(members, i); + assert(PyTuple_Check(m)); + assert(PyTuple_GET_SIZE(m) == allowOptional ? 5 : 3); + + PyObject* name = PyTuple_GET_ITEM(m, 0); // Member name. + assert(checkString(name)); + PyObject* meta = PyTuple_GET_ITEM(m, 1); // Member metadata. + assert(PyTuple_Check(meta)); + PyObject* t = PyTuple_GET_ITEM(m, 2); // Member type. + + PyObject* opt = 0; + PyObject* tag = 0; + if(allowOptional) + { + opt = PyTuple_GET_ITEM(m, 3); // Optional? + tag = PyTuple_GET_ITEM(m, 4); +#if PY_VERSION_HEX < 0x03000000 + assert(PyInt_Check(tag)); +#else + assert(PyLong_Check(tag)); +#endif + } + + DataMemberPtr member = new DataMember; + member->name = getString(name); +#ifndef NDEBUG + bool b = +#endif + tupleToStringSeq(meta, member->metaData); + assert(b); + member->type = getType(t); + if(allowOptional) + { + member->optional = PyObject_IsTrue(opt) == 1; + member->tag = static_cast<int>(PyLong_AsLong(tag)); + } + else + { + member->optional = false; + member->tag = 0; + } + + if(member->optional) + { + optList.push_back(member); + } + else + { + reqMembers.push_back(member); + } + } + + if(allowOptional) + { + class SortFn + { + public: + static bool compare(const DataMemberPtr& lhs, const DataMemberPtr& rhs) + { + return lhs->tag < rhs->tag; + } + }; + + optList.sort(SortFn::compare); + copy(optList.begin(), optList.end(), back_inserter(optMembers)); + } +} + +// +// StructInfo implementation. +// +IcePy::StructInfo::StructInfo(const string& ident, PyObject* t, PyObject* m) : + id(ident), pythonType(t) +{ + assert(PyType_Check(t)); + assert(PyTuple_Check(m)); + + Py_INCREF(t); + + DataMemberList opt; + convertDataMembers(m, const_cast<DataMemberList&>(members), opt, false); + assert(opt.empty()); + + _variableLength = false; + _wireSize = 0; + for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) + { + if(!_variableLength && (*p)->type->variableLength()) + { + _variableLength = true; + } + _wireSize += (*p)->type->wireSize(); + } +} + +string +IcePy::StructInfo::getId() const +{ + return id; +} + +bool +IcePy::StructInfo::validate(PyObject* val) +{ + return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; +} + +bool +IcePy::StructInfo::variableLength() const +{ + return _variableLength; +} + +int +IcePy::StructInfo::wireSize() const +{ + return _wireSize; +} + +Ice::OptionalFormat +IcePy::StructInfo::optionalFormat() const +{ + return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; +} + +bool +IcePy::StructInfo::usesClasses() const +{ + for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) + { + if((*p)->type->usesClasses()) + { + return true; + } + } + + return false; +} + +void +IcePy::StructInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional, + const Ice::StringSeq*) +{ + assert(p == Py_None || PyObject_IsInstance(p, pythonType.get()) == 1); // validate() should have caught this. + + if(p == Py_None) + { + if(!_nullMarshalValue.get()) + { + PyObjectHandle args = PyTuple_New(0); + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType.get()); + _nullMarshalValue = type->tp_new(type, args.get(), 0); + type->tp_init(_nullMarshalValue.get(), args.get(), 0); // Initialize the struct members + } + p = _nullMarshalValue.get(); + } + + Ice::OutputStream::size_type sizePos = 0; + if(optional) + { + if(_variableLength) + { + sizePos = os->startSize(); + } + else + { + os->writeSize(_wireSize); + } + } + + for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(p, memberName); + if(!attr.get()) + { + PyErr_Format(PyExc_AttributeError, STRCAST("no member `%s' found in %s value"), memberName, + const_cast<char*>(id.c_str())); + throw AbortMarshaling(); + } + if(!member->type->validate(attr.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for %s member `%s'"), const_cast<char*>(id.c_str()), + memberName); + throw AbortMarshaling(); + } + member->type->marshal(attr.get(), os, objectMap, false, &member->metaData); + } + + if(optional && _variableLength) + { + os->endSize(sizePos); + } +} + +void +IcePy::StructInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool optional, const Ice::StringSeq*) +{ + PyObjectHandle p = instantiate(pythonType.get()); + if(!p.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + if(optional) + { + if(_variableLength) + { + is->skip(4); + } + else + { + is->skipSize(); + } + } + + for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + member->type->unmarshal(is, member, p.get(), 0, false, &member->metaData); + } + + cb->unmarshaled(p.get(), target, closure); +} + +void +IcePy::StructInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(value == Py_None) + { + out << "<nil>"; + } + else + { + out.sb(); + for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(value, memberName); + out << nl << member->name << " = "; + if(!attr.get()) + { + out << "<not defined>"; + } + else + { + member->type->print(attr.get(), out, history); + } + } + out.eb(); + } +} + +void +IcePy::StructInfo::destroy() +{ + for(DataMemberList::const_iterator p = members.begin(); p != members.end(); ++p) + { + (*p)->type->destroy(); + } + const_cast<DataMemberList&>(members).clear(); + if(_nullMarshalValue.get()) + { + _nullMarshalValue.release(); + } +} + +PyObject* +IcePy::StructInfo::instantiate(PyObject* pythonType) +{ + PyObjectHandle args = PyTuple_New(0); + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType); + return type->tp_new(type, args.get(), 0); +} + +// +// SequenceInfo implementation. +// +IcePy::SequenceInfo::SequenceInfo(const string& ident, PyObject* m, PyObject* t) : + id(ident) +{ + assert(PyTuple_Check(m)); + + vector<string> metaData; +#ifndef NDEBUG + bool b = +#endif + tupleToStringSeq(m, metaData); + assert(b); + + const_cast<SequenceMappingPtr&>(mapping) = new SequenceMapping(metaData); + const_cast<TypeInfoPtr&>(elementType) = getType(t); +} + +string +IcePy::SequenceInfo::getId() const +{ + return id; +} + +bool +IcePy::SequenceInfo::validate(PyObject* val) +{ + return val == Py_None || PySequence_Check(val) == 1; +} + +bool +IcePy::SequenceInfo::variableLength() const +{ + return true; +} + +int +IcePy::SequenceInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::SequenceInfo::optionalFormat() const +{ + return elementType->variableLength() ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; +} + +bool +IcePy::SequenceInfo::usesClasses() const +{ + return elementType->usesClasses(); +} + +void +IcePy::SequenceInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional, + const Ice::StringSeq* metaData) +{ + PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + + Ice::OutputStream::size_type sizePos = 0; + if(optional) + { + if(elementType->variableLength()) + { + sizePos = os->startSize(); + } + else if(elementType->wireSize() > 1) + { + // + // Determine the sequence size. + // + Py_ssize_t sz = 0; + if(p != Py_None) + { + const void* buf = 0; + if(PyObject_AsReadBuffer(p, &buf, &sz) == 0) + { + if(pi->kind == PrimitiveInfo::KindString) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected sequence value")); + throw AbortMarshaling(); + } + } + else + { + PyErr_Clear(); // PyObject_AsReadBuffer sets an exception on failure. + + PyObjectHandle fs; + if(pi) + { + fs = getSequence(pi, p); + } + else + { + fs = PySequence_Fast(p, STRCAST("expected a sequence value")); + } + if(!fs.get()) + { + assert(PyErr_Occurred()); + return; + } + sz = PySequence_Fast_GET_SIZE(fs.get()); + } + } + + const Ice::Int isz = static_cast<Ice::Int>(sz); + os->writeSize(isz == 0 ? 1 : isz * elementType->wireSize() + (isz > 254 ? 5 : 1)); + } + } + + if(p == Py_None) + { + os->writeSize(0); + } + else if(pi) + { + marshalPrimitiveSequence(pi, p, os); + } + else + { + PyObjectHandle fastSeq = PySequence_Fast(p, STRCAST("expected a sequence value")); + if(!fastSeq.get()) + { + return; + } + + Py_ssize_t sz = PySequence_Fast_GET_SIZE(fastSeq.get()); + os->writeSize(static_cast<int>(sz)); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fastSeq.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + if(!elementType->validate(item)) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of `%s'"), static_cast<int>(i), + const_cast<char*>(id.c_str())); + throw AbortMarshaling(); + } + elementType->marshal(item, os, objectMap, false); + } + } + + if(optional && elementType->variableLength()) + { + os->endSize(sizePos); + } +} + +void +IcePy::SequenceInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool optional, const Ice::StringSeq* metaData) +{ + if(optional) + { + if(elementType->variableLength()) + { + is->skip(4); + } + else if(elementType->wireSize() > 1) + { + is->skipSize(); + } + } + + // + // Determine the mapping to use for this sequence. Highest priority is given + // to the metaData argument, otherwise we use the mapping of the sequence + // definition. + // + SequenceMappingPtr sm; + if(metaData) + { + SequenceMapping::Type type; + if(!SequenceMapping::getType(*metaData, type) || type == mapping->type) + { + sm = mapping; + } + else + { + sm = new SequenceMapping(type); + } + } + else + { + sm = mapping; + } + + PrimitiveInfoPtr pi = PrimitiveInfoPtr::dynamicCast(elementType); + if(pi) + { + unmarshalPrimitiveSequence(pi, is, cb, target, closure, sm); + return; + } + + Ice::Int sz = is->readSize(); + PyObjectHandle result = sm->createContainer(sz); + + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(Ice::Int i = 0; i < sz; ++i) + { + void* cl = reinterpret_cast<void*>(i); + elementType->unmarshal(is, sm, result.get(), cl, false); + } + + cb->unmarshaled(result.get(), target, closure); +} + +void +IcePy::SequenceInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(value == Py_None) + { + out << "{}"; + } + else + { + PyObjectHandle fastSeq = PySequence_Fast(value, STRCAST("expected a sequence value")); + if(!fastSeq.get()) + { + return; + } + + Py_ssize_t sz = PySequence_Fast_GET_SIZE(fastSeq.get()); + + out.sb(); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fastSeq.get(), i); + if(!item) + { + break; + } + out << nl << '[' << static_cast<int>(i) << "] = "; + elementType->print(item, out, history); + } + out.eb(); + } +} + +void +IcePy::SequenceInfo::destroy() +{ + if(elementType) + { + elementType->destroy(); + const_cast<TypeInfoPtr&>(elementType) = 0; + } +} + +PyObject* +IcePy::SequenceInfo::getSequence(const PrimitiveInfoPtr& pi, PyObject* p) +{ + PyObjectHandle fs; + + if(pi->kind == PrimitiveInfo::KindByte) + { +#if PY_VERSION_HEX >= 0x03000000 + // + // For sequence<byte>, accept a bytes object or a sequence. + // + if(!PyBytes_Check(p)) + { + fs = PySequence_Fast(p, STRCAST("expected a bytes, sequence, or buffer value")); + } +#else + // + // For sequence<byte>, accept a string or a sequence. + // + if(!checkString(p)) + { + fs = PySequence_Fast(p, STRCAST("expected a string, sequence, or buffer value")); + } +#endif + } + else + { + fs = PySequence_Fast(p, STRCAST("expected a sequence or buffer value")); + } + + return fs.release(); +} + +void +IcePy::SequenceInfo::marshalPrimitiveSequence(const PrimitiveInfoPtr& pi, PyObject* p, const Ice::OutputStreamPtr& os) +{ + // + // For most types, we accept an object that implements the buffer protocol + // (this includes the array.array type). + // + const void* buf = 0; + Py_ssize_t sz; + if(PyObject_AsReadBuffer(p, &buf, &sz) == 0) + { + const Ice::Byte* b = reinterpret_cast<const Ice::Byte*>(buf); + switch(pi->kind) + { + case PrimitiveInfo::KindBool: + { + os->write(reinterpret_cast<const bool*>(b), reinterpret_cast<const bool*>(b + sz)); + break; + } + case PrimitiveInfo::KindByte: + { + os->write(reinterpret_cast<const Ice::Byte*>(b), reinterpret_cast<const Ice::Byte*>(b + sz)); + break; + } + case PrimitiveInfo::KindShort: + { + os->write(reinterpret_cast<const Ice::Short*>(b), reinterpret_cast<const Ice::Short*>(b + sz)); + break; + } + case PrimitiveInfo::KindInt: + { + os->write(reinterpret_cast<const Ice::Int*>(b), reinterpret_cast<const Ice::Int*>(b + sz)); + break; + } + case PrimitiveInfo::KindLong: + { + os->write(reinterpret_cast<const Ice::Long*>(b), reinterpret_cast<const Ice::Long*>(b + sz)); + break; + } + case PrimitiveInfo::KindFloat: + { + os->write(reinterpret_cast<const Ice::Float*>(b), reinterpret_cast<const Ice::Float*>(b + sz)); + break; + } + case PrimitiveInfo::KindDouble: + { + os->write(reinterpret_cast<const Ice::Double*>(b), reinterpret_cast<const Ice::Double*>(b + sz)); + break; + } + case PrimitiveInfo::KindString: + { + PyErr_Format(PyExc_ValueError, STRCAST("expected sequence value")); + throw AbortMarshaling(); + } + } + return; + } + else + { + PyErr_Clear(); // PyObject_AsReadBuffer sets an exception on failure. + } + + PyObjectHandle fs = getSequence(pi, p); + if(!fs.get()) + { + assert(PyErr_Occurred()); + return; + } + + switch(pi->kind) + { + case PrimitiveInfo::KindBool: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::BoolSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + int isTrue = PyObject_IsTrue(item); + if(isTrue < 0) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<bool>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + seq[i] = isTrue ? true : false; + } + os->write(seq); + break; + } + case PrimitiveInfo::KindByte: + { + if(!fs.get()) + { +#if PY_VERSION_HEX >= 0x03000000 + assert(PyBytes_Check(p)); + char* str; + PyBytes_AsStringAndSize(p, &str, &sz); + os->write(reinterpret_cast<const Ice::Byte*>(str), reinterpret_cast<const Ice::Byte*>(str + sz)); +#else + assert(PyString_Check(p)); + char* str; + PyString_AsStringAndSize(p, &str, &sz); + os->write(reinterpret_cast<const Ice::Byte*>(str), reinterpret_cast<const Ice::Byte*>(str + sz)); +#endif + } + else + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::ByteSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + long val = PyLong_AsLong(item); + + if(PyErr_Occurred() || val < 0 || val > 255) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<byte>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + seq[i] = static_cast<Ice::Byte>(val); + } + os->write(seq); + } + break; + } + case PrimitiveInfo::KindShort: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::ShortSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + long val = PyLong_AsLong(item); + + if(PyErr_Occurred() || val < SHRT_MIN || val > SHRT_MAX) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<short>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + seq[i] = static_cast<Ice::Short>(val); + } + os->write(seq); + break; + } + case PrimitiveInfo::KindInt: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::IntSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + long val = PyLong_AsLong(item); + + if(PyErr_Occurred() || val < INT_MIN || val > INT_MAX) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<int>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + seq[i] = static_cast<Ice::Int>(val); + } + os->write(seq); + break; + } + case PrimitiveInfo::KindLong: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::LongSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + Ice::Long val = PyLong_AsLongLong(item); + + if(PyErr_Occurred()) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<long>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + seq[i] = val; + } + os->write(seq); + break; + } + case PrimitiveInfo::KindFloat: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::FloatSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + float val = static_cast<float>(PyFloat_AsDouble(item)); + if(PyErr_Occurred()) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<float>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + + seq[i] = val; + } + os->write(seq); + break; + } + case PrimitiveInfo::KindDouble: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + Ice::DoubleSeq seq(sz); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + double val = PyFloat_AsDouble(item); + if(PyErr_Occurred()) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<double>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + + seq[i] = val; + } + os->write(seq); + break; + } + case PrimitiveInfo::KindString: + { + sz = PySequence_Fast_GET_SIZE(fs.get()); + os->writeSize(static_cast<int>(sz)); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PySequence_Fast_GET_ITEM(fs.get(), i); + if(!item) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + +#if defined(Py_USING_UNICODE) && PY_VERSION_HEX < 0x03000000 + if(item != Py_None && !checkString(item) && !PyUnicode_Check(item)) +#else + if(item != Py_None && !checkString(item)) +#endif + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for element %d of sequence<string>"), + static_cast<int>(i)); + throw AbortMarshaling(); + } + + if(!writeString(item, os)) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + break; + } + } +} + +void +IcePy::SequenceInfo::unmarshalPrimitiveSequence(const PrimitiveInfoPtr& pi, const Ice::InputStreamPtr& is, + const UnmarshalCallbackPtr& cb, PyObject* target, void* closure, + const SequenceMappingPtr& sm) +{ + PyObjectHandle result; + + switch(pi->kind) + { + case PrimitiveInfo::KindBool: + { + pair<const bool*, const bool*> p; + IceUtil::ScopedArray<bool> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + sm->setItem(result.get(), i, p.first[i] ? getTrue() : getFalse()); + } + break; + } + case PrimitiveInfo::KindByte: + { + pair<const Ice::Byte*, const Ice::Byte*> p; + is->read(p); + int sz = static_cast<int>(p.second - p.first); + if(sm->type == SequenceMapping::SEQ_DEFAULT) + { +#if PY_VERSION_HEX >= 0x03000000 + result = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(p.first), sz); +#else + result = PyString_FromStringAndSize(reinterpret_cast<const char*>(p.first), sz); +#endif + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + else + { + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyLong_FromLong(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + } + break; + } + case PrimitiveInfo::KindShort: + { + pair<const Ice::Short*, const Ice::Short*> p; + IceUtil::ScopedArray<Ice::Short> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyLong_FromLong(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + case PrimitiveInfo::KindInt: + { + pair<const Ice::Int*, const Ice::Int*> p; + IceUtil::ScopedArray<Ice::Int> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyLong_FromLong(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + case PrimitiveInfo::KindLong: + { + pair<const Ice::Long*, const Ice::Long*> p; + IceUtil::ScopedArray<Ice::Long> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyLong_FromLongLong(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + case PrimitiveInfo::KindFloat: + { + pair<const Ice::Float*, const Ice::Float*> p; + IceUtil::ScopedArray<Ice::Float> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyFloat_FromDouble(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + case PrimitiveInfo::KindDouble: + { + pair<const Ice::Double*, const Ice::Double*> p; + IceUtil::ScopedArray<Ice::Double> arr; + is->read(p, arr); + int sz = static_cast<int>(p.second - p.first); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = PyFloat_FromDouble(p.first[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + case PrimitiveInfo::KindString: + { + Ice::StringSeq seq; + is->read(seq); + int sz = static_cast<int>(seq.size()); + result = sm->createContainer(sz); + if(!result.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + for(int i = 0; i < sz; ++i) + { + PyObjectHandle item = createString(seq[i]); + if(!item.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + sm->setItem(result.get(), i, item.get()); + } + break; + } + } + cb->unmarshaled(result.get(), target, closure); +} + +bool +IcePy::SequenceInfo::SequenceMapping::getType(const Ice::StringSeq& metaData, Type& t) +{ + if(!metaData.empty()) + { + for(Ice::StringSeq::const_iterator p = metaData.begin(); p != metaData.end(); ++p) + { + if((*p) == "python:seq:default") + { + t = SEQ_DEFAULT; + return true; + } + else if((*p) == "python:seq:tuple") + { + t = SEQ_TUPLE; + return true; + } + else if((*p) == "python:seq:list") + { + t = SEQ_LIST; + return true; + } + } + } + + return false; +} + +IcePy::SequenceInfo::SequenceMapping::SequenceMapping(Type t) : + type(t) +{ +} + +IcePy::SequenceInfo::SequenceMapping::SequenceMapping(const Ice::StringSeq& meta) +{ + if(!getType(meta, type)) + { + type = SEQ_DEFAULT; + } +} + +void +IcePy::SequenceInfo::SequenceMapping::unmarshaled(PyObject* val, PyObject* target, void* closure) +{ + long i = reinterpret_cast<long>(closure); + if(type == SEQ_DEFAULT || type == SEQ_LIST) + { + PyList_SET_ITEM(target, i, val); + Py_INCREF(val); // PyList_SET_ITEM steals a reference. + } + else + { + assert(type == SEQ_TUPLE); + PyTuple_SET_ITEM(target, i, val); + Py_INCREF(val); // PyTuple_SET_ITEM steals a reference. + } +} + +PyObject* +IcePy::SequenceInfo::SequenceMapping::createContainer(int sz) const +{ + if(type == SEQ_DEFAULT || type == SEQ_LIST) + { + return PyList_New(sz); + } + else + { + assert(type == SEQ_TUPLE); + return PyTuple_New(sz); + } +} + +void +IcePy::SequenceInfo::SequenceMapping::setItem(PyObject* cont, int i, PyObject* val) const +{ + if(type == SEQ_DEFAULT || type == SEQ_LIST) + { + Py_INCREF(val); + PyList_SET_ITEM(cont, i, val); // PyList_SET_ITEM steals a reference. + } + else + { + assert(type == SEQ_TUPLE); + Py_INCREF(val); + PyTuple_SET_ITEM(cont, i, val); // PyTuple_SET_ITEM steals a reference. + } +} + +// +// CustomInfo implementation. +// +IcePy::CustomInfo::CustomInfo(const string& ident, PyObject* t) : + id(ident), pythonType(t) +{ + assert(PyType_Check(t)); +} + +string +IcePy::CustomInfo::getId() const +{ + return id; +} + +bool +IcePy::CustomInfo::validate(PyObject* val) +{ + return PyObject_IsInstance(val, pythonType.get()) == 1; +} + +bool +IcePy::CustomInfo::variableLength() const +{ + return true; +} + +int +IcePy::CustomInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::CustomInfo::optionalFormat() const +{ + return Ice::OptionalFormatVSize; +} + +bool +IcePy::CustomInfo::usesClasses() const +{ + return false; +} + +void +IcePy::CustomInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool, + const Ice::StringSeq* metaData) +{ + assert(PyObject_IsInstance(p, pythonType.get()) == 1); // validate() should have caught this. + + PyObjectHandle obj = PyObject_CallMethod(p, STRCAST("IsInitialized"), 0); + if(!obj.get()) + { + throwPythonException(); + } + if(!PyObject_IsTrue(obj.get())) + { + setPythonException(Ice::MarshalException(__FILE__, __LINE__, "type not fully initialized")); + throw AbortMarshaling(); + } + + obj = PyObject_CallMethod(p, STRCAST("SerializeToString"), 0); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + assert(checkString(obj.get())); + char* str; + Py_ssize_t sz; +#if PY_VERSION_HEX >= 0x03000000 + PyBytes_AsStringAndSize(obj.get(), &str, &sz); +#else + PyString_AsStringAndSize(obj.get(), &str, &sz); +#endif + os->write(reinterpret_cast<const Ice::Byte*>(str), reinterpret_cast<const Ice::Byte*>(str + sz)); +} + +void +IcePy::CustomInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool, const Ice::StringSeq* metaData) +{ + // + // Unmarshal the raw byte sequence. + // + pair<const Ice::Byte*, const Ice::Byte*> seq; + is->read(seq); + int sz = static_cast<int>(seq.second - seq.first); + + // + // Create a new instance of the protobuf type. + // + PyObjectHandle args = PyTuple_New(0); + if(!args.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + PyTypeObject* type = reinterpret_cast<PyTypeObject*>(pythonType.get()); + PyObjectHandle p = type->tp_new(type, args.get(), 0); + if(!p.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // Initialize the object. + // + PyObjectHandle obj = PyObject_CallMethod(p.get(), STRCAST("__init__"), 0, 0); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // Convert the seq to a string. + // +#if PY_VERSION_HEX >= 0x03000000 + obj = PyBytes_FromStringAndSize(reinterpret_cast<const char*>(seq.first), sz); +#else + obj = PyString_FromStringAndSize(reinterpret_cast<const char*>(seq.first), sz); +#endif + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // Parse the string. + // + obj = PyObject_CallMethod(p.get(), STRCAST("ParseFromString"), STRCAST("O"), obj.get(), 0); + if(!obj.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + cb->unmarshaled(p.get(), target, closure); +} + +void +IcePy::CustomInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(value == Py_None) + { + out << "{}"; + } + else + { + } +} + +void +IcePy::CustomInfo::destroy() +{ +} + +// +// DictionaryInfo implementation. +// +IcePy::DictionaryInfo::DictionaryInfo(const string& ident, PyObject* kt, PyObject* vt) : + id(ident) +{ + const_cast<TypeInfoPtr&>(keyType) = getType(kt); + const_cast<TypeInfoPtr&>(valueType) = getType(vt); + + _variableLength = keyType->variableLength() || valueType->variableLength(); + _wireSize = keyType->wireSize() + valueType->wireSize(); +} + +string +IcePy::DictionaryInfo::getId() const +{ + return id; +} + +bool +IcePy::DictionaryInfo::validate(PyObject* val) +{ + return val == Py_None || PyDict_Check(val) == 1; +} + +bool +IcePy::DictionaryInfo::variableLength() const +{ + return true; +} + +int +IcePy::DictionaryInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::DictionaryInfo::optionalFormat() const +{ + return _variableLength ? Ice::OptionalFormatFSize : Ice::OptionalFormatVSize; +} + +bool +IcePy::DictionaryInfo::usesClasses() const +{ + return valueType->usesClasses(); +} + +void +IcePy::DictionaryInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool optional, + const Ice::StringSeq*) +{ + if(p != Py_None && !PyDict_Check(p)) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected dictionary value")); + throw AbortMarshaling(); + } + + const Ice::Int sz = p == Py_None ? 0 : static_cast<Ice::Int>(PyDict_Size(p)); + + Ice::OutputStream::size_type sizePos = 0; + if(optional) + { + if(_variableLength) + { + sizePos = os->startSize(); + } + else + { + os->writeSize(sz == 0 ? 1 : sz * _wireSize + (sz > 254 ? 5 : 1)); + } + } + + if(p == Py_None) + { + os->writeSize(0); + } + else + { + os->writeSize(sz); + + Py_ssize_t pos = 0; + PyObject* key; + PyObject* value; + while(PyDict_Next(p, &pos, &key, &value)) + { + if(!keyType->validate(key)) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid key in `%s' element"), const_cast<char*>(id.c_str())); + throw AbortMarshaling(); + } + keyType->marshal(key, os, objectMap, false); + + if(!valueType->validate(value)) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value in `%s' element"), const_cast<char*>(id.c_str())); + throw AbortMarshaling(); + } + valueType->marshal(value, os, objectMap, false); + } + } + + if(optional && _variableLength) + { + os->endSize(sizePos); + } +} + +void +IcePy::DictionaryInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool optional, const Ice::StringSeq*) +{ + if(optional) + { + if(_variableLength) + { + is->skip(4); + } + else + { + is->skipSize(); + } + } + + PyObjectHandle p = PyDict_New(); + if(!p.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + KeyCallbackPtr keyCB = new KeyCallback; + keyCB->key = 0; + + Ice::Int sz = is->readSize(); + for(Ice::Int i = 0; i < sz; ++i) + { + // + // A dictionary key cannot be a class (or contain one), so the key must be + // available immediately. + // + keyType->unmarshal(is, keyCB, 0, 0, false); + assert(keyCB->key.get()); + + // + // Insert the key into the dictionary with a dummy value in order to hold + // a reference to the key. In case of an exception, we don't want to leak + // the key. + // + if(PyDict_SetItem(p.get(), keyCB->key.get(), Py_None) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + + // + // The callback will reset the dictionary entry with the unmarshaled value, + // so we pass it the key. + // + void* cl = reinterpret_cast<void*>(keyCB->key.get()); + valueType->unmarshal(is, this, p.get(), cl, false); + } + + cb->unmarshaled(p.get(), target, closure); +} + +void +IcePy::DictionaryInfo::unmarshaled(PyObject* val, PyObject* target, void* closure) +{ + PyObject* key = reinterpret_cast<PyObject*>(closure); + if(PyDict_SetItem(target, key, val) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } +} + +void +IcePy::DictionaryInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(value == Py_None) + { + out << "{}"; + } + else + { + Py_ssize_t pos = 0; + PyObject* elemKey; + PyObject* elemValue; + out.sb(); + bool first = true; + while(PyDict_Next(value, &pos, &elemKey, &elemValue)) + { + if(first) + { + first = false; + } + else + { + out << nl; + } + out << nl << "key = "; + keyType->print(elemKey, out, history); + out << nl << "value = "; + valueType->print(elemValue, out, history); + } + out.eb(); + } +} + +void +IcePy::DictionaryInfo::KeyCallback::unmarshaled(PyObject* val, PyObject*, void*) +{ + key = val; + Py_INCREF(val); +} + +void +IcePy::DictionaryInfo::destroy() +{ + if(keyType) + { + keyType->destroy(); + keyType = 0; + } + if(valueType) + { + valueType->destroy(); + valueType = 0; + } +} + +// +// ClassInfo implementation. +// +IcePy::ClassInfo::ClassInfo(const string& ident) : + id(ident), compactId(-1), isAbstract(false), preserve(false), defined(false) +{ + const_cast<PyObjectHandle&>(typeObj) = createType(this); +} + +void +IcePy::ClassInfo::define(PyObject* t, int compact, bool abstr, bool pres, PyObject* b, PyObject* i, PyObject* m) +{ + assert(PyType_Check(t)); + assert(PyTuple_Check(i)); + assert(PyTuple_Check(m)); + + const_cast<int&>(compactId) = compact; + const_cast<bool&>(isAbstract) = abstr; + const_cast<bool&>(preserve) = pres; + + if(b != Py_None) + { + const_cast<ClassInfoPtr&>(base) = ClassInfoPtr::dynamicCast(getType(b)); + assert(base); + } + + Py_ssize_t n, sz; + sz = PyTuple_GET_SIZE(i); + for(n = 0; n < sz; ++n) + { + PyObject* o = PyTuple_GET_ITEM(i, n); + ClassInfoPtr iface = ClassInfoPtr::dynamicCast(getType(o)); + assert(iface); + const_cast<ClassInfoList&>(interfaces).push_back(iface); + } + + convertDataMembers(m, const_cast<DataMemberList&>(members), const_cast<DataMemberList&>(optionalMembers), true); + + const_cast<PyObjectHandle&>(pythonType) = t; + Py_INCREF(t); + + const_cast<bool&>(defined) = true; +} + +string +IcePy::ClassInfo::getId() const +{ + return id; +} + +bool +IcePy::ClassInfo::validate(PyObject* val) +{ + return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; +} + +bool +IcePy::ClassInfo::variableLength() const +{ + return true; +} + +int +IcePy::ClassInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::ClassInfo::optionalFormat() const +{ + return Ice::OptionalFormatClass; +} + +bool +IcePy::ClassInfo::usesClasses() const +{ + return true; +} + +void +IcePy::ClassInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap, bool, + const Ice::StringSeq*) +{ + if(!pythonType.get()) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); + throw AbortMarshaling(); + } + + if(p == Py_None) + { + os->writeObject(0); + return; + } + + if(!PyObject_IsInstance(p, pythonType.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected value of type %s"), id.c_str()); + throw AbortMarshaling(); + } + + // + // Ice::ObjectWriter is a subclass of Ice::Object that wraps a Python object for marshaling. + // It is possible that this Python object has already been marshaled, therefore we first must + // check the object map to see if this object is present. If so, we use the existing ObjectWriter, + // otherwise we create a new one. + // + Ice::ObjectPtr writer; + assert(objectMap); + ObjectMap::iterator q = objectMap->find(p); + if(q == objectMap->end()) + { + writer = new ObjectWriter(p, objectMap); + objectMap->insert(ObjectMap::value_type(p, writer)); + } + else + { + writer = q->second; + } + + // + // Give the writer to the stream. The stream will eventually call write() on it. + // + os->writeObject(writer); +} + +void +IcePy::ClassInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool, const Ice::StringSeq*) +{ + if(!pythonType.get()) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); + throw AbortMarshaling(); + } + + is->readObject(new ReadObjectCallback(this, cb, target, closure)); +} + +void +IcePy::ClassInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + if(value == Py_None) + { + out << "<nil>"; + } + else + { + map<PyObject*, int>::iterator q = history->objects.find(value); + if(q != history->objects.end()) + { + out << "<object #" << q->second << ">"; + } + else + { + PyObjectHandle iceType = PyObject_GetAttrString(value, STRCAST("_ice_type")); + ClassInfoPtr info; + if(!iceType.get()) + { + // + // The _ice_type attribute will be missing in an instance of LocalObject + // that does not derive from a user-defined type. + // + assert(id == "::Ice::LocalObject"); + info = this; + } + else + { + info = ClassInfoPtr::dynamicCast(getType(iceType.get())); + assert(info); + } + out << "object #" << history->index << " (" << info->id << ')'; + history->objects.insert(map<PyObject*, int>::value_type(value, history->index)); + ++history->index; + out.sb(); + info->printMembers(value, out, history); + out.eb(); + } + } +} + +void +IcePy::ClassInfo::destroy() +{ + const_cast<ClassInfoPtr&>(base) = 0; + const_cast<ClassInfoList&>(interfaces).clear(); + if(!members.empty()) + { + DataMemberList ml = members; + const_cast<DataMemberList&>(members).clear(); + for(DataMemberList::iterator p = ml.begin(); p != ml.end(); ++p) + { + (*p)->type->destroy(); + } + } + const_cast<PyObjectHandle&>(typeObj) = 0; // Break circular reference. +} + +void +IcePy::ClassInfo::printMembers(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(base) + { + base->printMembers(value, out, history); + } + + DataMemberList::const_iterator q; + + for(q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(value, memberName); + out << nl << member->name << " = "; + if(!attr.get()) + { + out << "<not defined>"; + } + else + { + member->type->print(attr.get(), out, history); + } + } + + for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(value, memberName); + out << nl << member->name << " = "; + if(!attr.get()) + { + out << "<not defined>"; + } + else if(attr.get() == Unset) + { + out << "<unset>"; + } + else + { + member->type->print(attr.get(), out, history); + } + } +} + +// +// ProxyInfo implementation. +// +IcePy::ProxyInfo::ProxyInfo(const string& ident) : + id(ident) +{ + const_cast<PyObjectHandle&>(typeObj) = createType(this); +} + +void +IcePy::ProxyInfo::define(PyObject* t) +{ + const_cast<PyObjectHandle&>(pythonType) = t; + Py_INCREF(t); +} + +string +IcePy::ProxyInfo::getId() const +{ + return id; +} + +bool +IcePy::ProxyInfo::validate(PyObject* val) +{ + return val == Py_None || PyObject_IsInstance(val, pythonType.get()) == 1; +} + +bool +IcePy::ProxyInfo::variableLength() const +{ + return true; +} + +int +IcePy::ProxyInfo::wireSize() const +{ + return 1; +} + +Ice::OptionalFormat +IcePy::ProxyInfo::optionalFormat() const +{ + return Ice::OptionalFormatFSize; +} + +void +IcePy::ProxyInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap*, bool optional, const Ice::StringSeq*) +{ + Ice::OutputStream::size_type sizePos = 0; + if(optional) + { + sizePos = os->startSize(); + } + + if(p == Py_None) + { + os->write(Ice::ObjectPrx()); + } + else if(checkProxy(p)) + { + os->write(getProxy(p)); + } + else + { + assert(false); // validate() should have caught this. + } + + if(optional) + { + os->endSize(sizePos); + } +} + +void +IcePy::ProxyInfo::unmarshal(const Ice::InputStreamPtr& is, const UnmarshalCallbackPtr& cb, PyObject* target, + void* closure, bool optional, const Ice::StringSeq*) +{ + if(optional) + { + is->skip(4); + } + + Ice::ObjectPrx proxy; + is->read(proxy); + + if(!proxy) + { + cb->unmarshaled(Py_None, target, closure); + return; + } + + if(!pythonType.get()) + { + PyErr_Format(PyExc_RuntimeError, STRCAST("class %s is declared but not defined"), id.c_str()); + throw AbortMarshaling(); + } + + PyObjectHandle p = createProxy(proxy, is->communicator(), pythonType.get()); + cb->unmarshaled(p.get(), target, closure); +} + +void +IcePy::ProxyInfo::print(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory*) +{ + if(!validate(value)) + { + out << "<invalid value - expected " << getId() << ">"; + return; + } + + if(value == Py_None) + { + out << "<nil>"; + } + else + { + PyObjectHandle p = PyObject_Str(value); + if(!p.get()) + { + return; + } + assert(checkString(p.get())); + out << getString(p.get()); + } +} + +void +IcePy::ProxyInfo::destroy() +{ + const_cast<PyObjectHandle&>(typeObj) = 0; // Break circular reference. +} + +// +// ObjectWriter implementation. +// +IcePy::ObjectWriter::ObjectWriter(PyObject* object, ObjectMap* objectMap) : + _object(object), _map(objectMap) +{ + Py_INCREF(_object); + + PyObjectHandle iceType = PyObject_GetAttrString(object, STRCAST("_ice_type")); + if(!iceType.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + _info = ClassInfoPtr::dynamicCast(getType(iceType.get())); + assert(_info); +} + +IcePy::ObjectWriter::~ObjectWriter() +{ + Py_DECREF(_object); +} + +void +IcePy::ObjectWriter::ice_preMarshal() +{ + if(PyObject_HasAttrString(_object, STRCAST("ice_preMarshal")) == 1) + { + PyObjectHandle tmp = PyObject_CallMethod(_object, STRCAST("ice_preMarshal"), 0); + if(!tmp.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } +} + +void +IcePy::ObjectWriter::write(const Ice::OutputStreamPtr& os) const +{ + Ice::SlicedDataPtr slicedData; + + if(_info->preserve) + { + // + // Retrieve the SlicedData object that we stored as a hidden member of the Python object. + // + slicedData = SlicedDataUtil::getMember(_object, const_cast<ObjectMap*>(_map)); + } + + os->startObject(slicedData); + + if(_info->id != "::Ice::UnknownSlicedObject") + { + ClassInfoPtr info = _info; + while(info) + { + os->startSlice(info->id, info->compactId, !info->base); + + writeMembers(os, info->members); + writeMembers(os, info->optionalMembers); // The optional members have already been sorted by tag. + + os->endSlice(); + + info = info->base; + } + } + + os->endObject(); +} + +void +IcePy::ObjectWriter::writeMembers(const Ice::OutputStreamPtr& os, const DataMemberList& members) const +{ + for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + char* memberName = const_cast<char*>(member->name.c_str()); + + PyObjectHandle val = PyObject_GetAttrString(_object, memberName); + if(!val.get()) + { + if(member->optional) + { + PyErr_Clear(); + continue; + } + else + { + PyErr_Format(PyExc_AttributeError, STRCAST("no member `%s' found in %s value"), memberName, + const_cast<char*>(_info->id.c_str())); + throw AbortMarshaling(); + } + } + else if(member->optional && + (val.get() == Unset || !os->writeOptional(member->tag, member->type->optionalFormat()))) + { + continue; + } + + if(!member->type->validate(val.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for %s member `%s'"), + const_cast<char*>(_info->id.c_str()), memberName); + throw AbortMarshaling(); + } + + member->type->marshal(val.get(), os, _map, member->optional, &member->metaData); + } +} + +// +// ObjectReader implementation. +// +IcePy::ObjectReader::ObjectReader(PyObject* object, const ClassInfoPtr& info) : + _object(object), _info(info) +{ + Py_INCREF(_object); +} + +IcePy::ObjectReader::~ObjectReader() +{ + Py_DECREF(_object); +} + +void +IcePy::ObjectReader::ice_postUnmarshal() +{ + if(PyObject_HasAttrString(_object, STRCAST("ice_postUnmarshal")) == 1) + { + PyObjectHandle tmp = PyObject_CallMethod(_object, STRCAST("ice_postUnmarshal"), 0); + if(!tmp.get()) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } +} + +void +IcePy::ObjectReader::read(const Ice::InputStreamPtr& is) +{ + is->startObject(); + + const bool unknown = _info->id == "::Ice::UnknownSlicedObject"; + + // + // Unmarshal the slices of a user-defined class. + // + if(!unknown && _info->id != Ice::Object::ice_staticId()) + { + ClassInfoPtr info = _info; + while(info) + { + is->startSlice(); + + DataMemberList::const_iterator p; + + for(p = info->members.begin(); p != info->members.end(); ++p) + { + DataMemberPtr member = *p; + member->type->unmarshal(is, member, _object, 0, false, &member->metaData); + } + + // + // The optional members have already been sorted by tag. + // + for(p = info->optionalMembers.begin(); p != info->optionalMembers.end(); ++p) + { + DataMemberPtr member = *p; + if(is->readOptional(member->tag, member->type->optionalFormat())) + { + member->type->unmarshal(is, member, _object, 0, true, &member->metaData); + } + else if(PyObject_SetAttrString(_object, const_cast<char*>(member->name.c_str()), Unset) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + + is->endSlice(); + + info = info->base; + } + } + + _slicedData = is->endObject(_info->preserve); + + if(_slicedData) + { + SlicedDataUtil* util = reinterpret_cast<SlicedDataUtil*>(is->closure()); + assert(util); + util->add(this); + + // + // Define the "unknownTypeId" member for an instance of UnknownSlicedObject. + // + if(unknown) + { + assert(!_slicedData->slices.empty()); + + PyObjectHandle typeId = createString(_slicedData->slices[0]->typeId); + if(!typeId.get() || PyObject_SetAttrString(_object, STRCAST("unknownTypeId"), typeId.get()) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + } +} + +ClassInfoPtr +IcePy::ObjectReader::getInfo() const +{ + return _info; +} + +PyObject* +IcePy::ObjectReader::getObject() const +{ + return _object; +} + +Ice::SlicedDataPtr +IcePy::ObjectReader::getSlicedData() const +{ + return _slicedData; +} + +// +// InfoMapDestroyer implementation. +// +IcePy::InfoMapDestroyer::~InfoMapDestroyer() +{ + { + for(ProxyInfoMap::iterator p = _proxyInfoMap.begin(); p != _proxyInfoMap.end(); ++p) + { + p->second->destroy(); + } + } + { + for(ClassInfoMap::iterator p = _classInfoMap.begin(); p != _classInfoMap.end(); ++p) + { + p->second->destroy(); + } + } + _compactIdMap.clear(); + _exceptionInfoMap.clear(); +} + +// +// ReadObjectCallback implementation. +// +IcePy::ReadObjectCallback::ReadObjectCallback(const ClassInfoPtr& info, const UnmarshalCallbackPtr& cb, + PyObject* target, void* closure) : + _info(info), _cb(cb), _target(target), _closure(closure) +{ + Py_XINCREF(_target); +} + +IcePy::ReadObjectCallback::~ReadObjectCallback() +{ + Py_XDECREF(_target); +} + +void +IcePy::ReadObjectCallback::invoke(const Ice::ObjectPtr& p) +{ + if(p) + { + ObjectReaderPtr reader = ObjectReaderPtr::dynamicCast(p); + assert(reader); + + // + // Verify that the object's type is compatible with the formal type. + // + PyObject* obj = reader->getObject(); // Borrowed reference. + if(!PyObject_IsInstance(obj, _info->pythonType.get())) + { + Ice::UnexpectedObjectException ex(__FILE__, __LINE__); + ex.reason = "unmarshaled object is not an instance of " + _info->id; + ex.type = reader->getInfo()->getId(); + ex.expectedType = _info->id; + throw ex; + } + + _cb->unmarshaled(obj, _target, _closure); + } + else + { + _cb->unmarshaled(Py_None, _target, _closure); + } +} + +// +// ExceptionInfo implementation. +// +void +IcePy::ExceptionInfo::marshal(PyObject* p, const Ice::OutputStreamPtr& os, ObjectMap* objectMap) +{ + if(!PyObject_IsInstance(p, pythonType.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("expected exception %s"), id.c_str()); + throw AbortMarshaling(); + } + + Ice::SlicedDataPtr slicedData; + + if(preserve) + { + // + // Retrieve the SlicedData object that we stored as a hidden member of the Python object. + // + slicedData = SlicedDataUtil::getMember(p, objectMap); + } + + os->startException(slicedData); + + ExceptionInfoPtr info = this; + while(info) + { + os->startSlice(info->id, -1, !info->base); + + writeMembers(p, os, info->members, objectMap); + writeMembers(p, os, info->optionalMembers, objectMap); // The optional members have already been sorted by tag. + + os->endSlice(); + + info = info->base; + } + + os->endException(); +} + +void +IcePy::ExceptionInfo::writeMembers(PyObject* p, const Ice::OutputStreamPtr& os, const DataMemberList& members, + ObjectMap* objectMap) const +{ + for(DataMemberList::const_iterator q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + + char* memberName = const_cast<char*>(member->name.c_str()); + + PyObjectHandle val = PyObject_GetAttrString(p, memberName); + if(!val.get()) + { + if(member->optional) + { + PyErr_Clear(); + continue; + } + else + { + PyErr_Format(PyExc_AttributeError, STRCAST("no member `%s' found in %s value"), memberName, + const_cast<char*>(id.c_str())); + throw AbortMarshaling(); + } + } + else if(member->optional && + (val.get() == Unset || !os->writeOptional(member->tag, member->type->optionalFormat()))) + { + continue; + } + + if(!member->type->validate(val.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("invalid value for %s member `%s'"), + const_cast<char*>(id.c_str()), memberName); + throw AbortMarshaling(); + } + + member->type->marshal(val.get(), os, objectMap, member->optional, &member->metaData); + } +} + +PyObject* +IcePy::ExceptionInfo::unmarshal(const Ice::InputStreamPtr& is) +{ + PyObjectHandle p = createExceptionInstance(pythonType.get()); + + ExceptionInfoPtr info = this; + while(info) + { + is->startSlice(); + + DataMemberList::iterator q; + + for(q = info->members.begin(); q != info->members.end(); ++q) + { + DataMemberPtr member = *q; + member->type->unmarshal(is, member, p.get(), 0, false, &member->metaData); + } + + // + // The optional members have already been sorted by tag. + // + for(q = info->optionalMembers.begin(); q != info->optionalMembers.end(); ++q) + { + DataMemberPtr member = *q; + if(is->readOptional(member->tag, member->type->optionalFormat())) + { + member->type->unmarshal(is, member, p.get(), 0, true, &member->metaData); + } + else if(PyObject_SetAttrString(p.get(), const_cast<char*>(member->name.c_str()), Unset) < 0) + { + assert(PyErr_Occurred()); + throw AbortMarshaling(); + } + } + + is->endSlice(); + + info = info->base; + } + + return p.release(); +} + +void +IcePy::ExceptionInfo::print(PyObject* value, IceUtilInternal::Output& out) +{ + if(!PyObject_IsInstance(value, pythonType.get())) + { + out << "<invalid value - expected " << id << ">"; + return; + } + + PrintObjectHistory history; + history.index = 0; + + out << "exception " << id; + out.sb(); + printMembers(value, out, &history); + out.eb(); +} + +void +IcePy::ExceptionInfo::printMembers(PyObject* value, IceUtilInternal::Output& out, PrintObjectHistory* history) +{ + if(base) + { + base->printMembers(value, out, history); + } + + DataMemberList::iterator q; + + for(q = members.begin(); q != members.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(value, memberName); + out << nl << member->name << " = "; + if(!attr.get() || attr.get() == Unset) + { + out << "<not defined>"; + } + else + { + member->type->print(attr.get(), out, history); + } + } + + for(q = optionalMembers.begin(); q != optionalMembers.end(); ++q) + { + DataMemberPtr member = *q; + char* memberName = const_cast<char*>(member->name.c_str()); + PyObjectHandle attr = PyObject_GetAttrString(value, memberName); + out << nl << member->name << " = "; + if(!attr.get()) + { + out << "<not defined>"; + } + else if(attr.get() == Unset) + { + out << "<unset>"; + } + else + { + member->type->print(attr.get(), out, history); + } + } +} + +// +// ExceptionWriter implementation. +// +IcePy::ExceptionWriter::ExceptionWriter(const Ice::CommunicatorPtr& communicator, const PyObjectHandle& ex, + const ExceptionInfoPtr& info) : + Ice::UserExceptionWriter(communicator), _ex(ex), _info(info) +{ + if(!info) + { + PyObjectHandle iceType = PyObject_GetAttrString(ex.get(), STRCAST("_ice_type")); + assert(iceType.get()); + _info = ExceptionInfoPtr::dynamicCast(getException(iceType.get())); + assert(_info); + } +} + +IcePy::ExceptionWriter::~ExceptionWriter() throw() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + _ex = 0; +} + +void +IcePy::ExceptionWriter::write(const Ice::OutputStreamPtr& os) const +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + _info->marshal(_ex.get(), os, const_cast<ObjectMap*>(&_objects)); +} + +bool +IcePy::ExceptionWriter::usesClasses() const +{ + return _info->usesClasses; +} + +string +IcePy::ExceptionWriter::ice_name() const +{ + return _info->id; +} + +Ice::UserException* +IcePy::ExceptionWriter::ice_clone() const +{ + return new ExceptionWriter(*this); +} + +void +IcePy::ExceptionWriter::ice_throw() const +{ + throw *this; +} + +// +// ExceptionReader implementation. +// +IcePy::ExceptionReader::ExceptionReader(const Ice::CommunicatorPtr& communicator, const ExceptionInfoPtr& info) : + Ice::UserExceptionReader(communicator), _info(info) +{ +} + +IcePy::ExceptionReader::~ExceptionReader() throw() +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + _ex = 0; +} + +void +IcePy::ExceptionReader::read(const Ice::InputStreamPtr& is) const +{ + AdoptThread adoptThread; // Ensure the current thread is able to call into Python. + + is->startException(); + + const_cast<PyObjectHandle&>(_ex) = _info->unmarshal(is); + + const_cast<Ice::SlicedDataPtr&>(_slicedData) = is->endException(_info->preserve); +} + +bool +IcePy::ExceptionReader::usesClasses() const +{ + return _info->usesClasses; +} + +string +IcePy::ExceptionReader::ice_name() const +{ + return _info->id; +} + +Ice::UserException* +IcePy::ExceptionReader::ice_clone() const +{ + assert(false); + return 0; +} + +void +IcePy::ExceptionReader::ice_throw() const +{ + throw *this; +} + +PyObject* +IcePy::ExceptionReader::getException() const +{ + return _ex.get(); +} + +Ice::SlicedDataPtr +IcePy::ExceptionReader::getSlicedData() const +{ + return _slicedData; +} + +// +// IdResolver +// +string +IcePy::IdResolver::resolve(Ice::Int id) const +{ + CompactIdMap::iterator p = _compactIdMap.find(id); + if(p != _compactIdMap.end()) + { + return p->second->id; + } + return string(); +} + +// +// lookupClassInfo() +// +IcePy::ClassInfoPtr +IcePy::lookupClassInfo(const string& id) +{ + ClassInfoMap::iterator p = _classInfoMap.find(id); + if(p != _classInfoMap.end()) + { + return p->second; + } + return 0; +} + +// +// lookupExceptionInfo() +// +IcePy::ExceptionInfoPtr +IcePy::lookupExceptionInfo(const string& id) +{ + ExceptionInfoMap::iterator p = _exceptionInfoMap.find(id); + if(p != _exceptionInfoMap.end()) + { + return p->second; + } + return 0; +} + +namespace IcePy +{ + +PyTypeObject TypeInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.TypeInfo"), /* tp_name */ + sizeof(TypeInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(typeInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(typeInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +PyTypeObject ExceptionInfoType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(0, 0) + STRCAST("IcePy.ExceptionInfo"), /* tp_name */ + sizeof(ExceptionInfoObject), /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(exceptionInfoDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + 0, /* tp_repr */ + 0, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + reinterpret_cast<newfunc>(exceptionInfoNew), /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +static PyNumberMethods UnsetAsNumber = +{ + 0, /* nb_add */ + 0, /* nb_subtract */ + 0, /* nb_multiply */ +#if PY_VERSION_HEX < 0x03000000 + 0, /* nb_divide */ +#endif + 0, /* nb_remainder */ + 0, /* nb_divmod */ + 0, /* nb_power */ + 0, /* nb_negative */ + 0, /* nb_positive */ + 0, /* nb_absolute */ + reinterpret_cast<inquiry>(unsetNonzero), /* nb_nonzero/nb_bool */ +}; + +PyTypeObject UnsetType = +{ + /* The ob_type field must be initialized in the module init function + * to be portable to Windows without using C++. */ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + STRCAST("IcePy.UnsetType"), /* tp_name */ + 0, /* tp_basicsize */ + 0, /* tp_itemsize */ + /* methods */ + reinterpret_cast<destructor>(unsetDealloc), /* tp_dealloc */ + 0, /* tp_print */ + 0, /* tp_getattr */ + 0, /* tp_setattr */ + 0, /* tp_reserved */ + reinterpret_cast<reprfunc>(unsetRepr), /* tp_repr */ + &UnsetAsNumber, /* tp_as_number */ + 0, /* tp_as_sequence */ + 0, /* tp_as_mapping */ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT, /* tp_flags */ + 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ + 0, /* tp_free */ + 0, /* tp_is_gc */ +}; + +// +// Unset is a singleton, similar to None. +// +PyObject UnsetValue = +{ + _PyObject_EXTRA_INIT + 1, &UnsetType +}; + +PyObject* Unset = &UnsetValue; + +} + +bool +IcePy::initTypes(PyObject* module) +{ + if(PyType_Ready(&TypeInfoType) < 0) + { + return false; + } + PyTypeObject* typeInfoType = &TypeInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("TypeInfo"), reinterpret_cast<PyObject*>(typeInfoType)) < 0) + { + return false; + } + + if(PyType_Ready(&ExceptionInfoType) < 0) + { + return false; + } + PyTypeObject* exceptionInfoType = &ExceptionInfoType; // Necessary to prevent GCC's strict-alias warnings. + if(PyModule_AddObject(module, STRCAST("ExceptionInfo"), reinterpret_cast<PyObject*>(exceptionInfoType)) < 0) + { + return false; + } + + PrimitiveInfoPtr boolType = new PrimitiveInfo(PrimitiveInfo::KindBool); + PyObjectHandle boolTypeObj = createType(boolType); + if(PyModule_AddObject(module, STRCAST("_t_bool"), boolTypeObj.get()) < 0) + { + return false; + } + boolTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr byteType = new PrimitiveInfo(PrimitiveInfo::KindByte); + PyObjectHandle byteTypeObj = createType(byteType); + if(PyModule_AddObject(module, STRCAST("_t_byte"), byteTypeObj.get()) < 0) + { + return false; + } + byteTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr shortType = new PrimitiveInfo(PrimitiveInfo::KindShort); + PyObjectHandle shortTypeObj = createType(shortType); + if(PyModule_AddObject(module, STRCAST("_t_short"), shortTypeObj.get()) < 0) + { + return false; + } + shortTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr intType = new PrimitiveInfo(PrimitiveInfo::KindInt); + PyObjectHandle intTypeObj = createType(intType); + if(PyModule_AddObject(module, STRCAST("_t_int"), intTypeObj.get()) < 0) + { + return false; + } + intTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr longType = new PrimitiveInfo(PrimitiveInfo::KindLong); + PyObjectHandle longTypeObj = createType(longType); + if(PyModule_AddObject(module, STRCAST("_t_long"), longTypeObj.get()) < 0) + { + return false; + } + longTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr floatType = new PrimitiveInfo(PrimitiveInfo::KindFloat); + PyObjectHandle floatTypeObj = createType(floatType); + if(PyModule_AddObject(module, STRCAST("_t_float"), floatTypeObj.get()) < 0) + { + return false; + } + floatTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr doubleType = new PrimitiveInfo(PrimitiveInfo::KindDouble); + PyObjectHandle doubleTypeObj = createType(doubleType); + if(PyModule_AddObject(module, STRCAST("_t_double"), doubleTypeObj.get()) < 0) + { + return false; + } + doubleTypeObj.release(); // PyModule_AddObject steals a reference. + + PrimitiveInfoPtr stringType = new PrimitiveInfo(PrimitiveInfo::KindString); + PyObjectHandle stringTypeObj = createType(stringType); + if(PyModule_AddObject(module, STRCAST("_t_string"), stringTypeObj.get()) < 0) + { + return false; + } + stringTypeObj.release(); // PyModule_AddObject steals a reference. + + if(PyModule_AddObject(module, STRCAST("Unset"), Unset) < 0) + { + return false; + } + Py_IncRef(Unset); // PyModule_AddObject steals a reference. + + return true; +} + +IcePy::TypeInfoPtr +IcePy::getType(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&TypeInfoType))); + TypeInfoObject* p = reinterpret_cast<TypeInfoObject*>(obj); + return *p->info; +} + +PyObject* +IcePy::createType(const TypeInfoPtr& info) +{ + TypeInfoObject* obj = typeInfoNew(&TypeInfoType, 0, 0); + if(obj) + { + obj->info = new IcePy::TypeInfoPtr(info); + } + return reinterpret_cast<PyObject*>(obj); +} + +IcePy::ExceptionInfoPtr +IcePy::getException(PyObject* obj) +{ + assert(PyObject_IsInstance(obj, reinterpret_cast<PyObject*>(&ExceptionInfoType))); + ExceptionInfoObject* p = reinterpret_cast<ExceptionInfoObject*>(obj); + return *p->info; +} + +PyObject* +IcePy::createException(const ExceptionInfoPtr& info) +{ + ExceptionInfoObject* obj = exceptionInfoNew(&ExceptionInfoType, 0, 0); + if(obj) + { + obj->info = new IcePy::ExceptionInfoPtr(info); + } + return reinterpret_cast<PyObject*>(obj); +} + +extern "C" +PyObject* +IcePy_defineEnum(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + PyObject* meta; // Not currently used. + PyObject* enumerators; + if(!PyArg_ParseTuple(args, STRCAST("sOOO"), &id, &type, &meta, &enumerators)) + { + return 0; + } + + assert(PyTuple_Check(meta)); + + EnumInfoPtr info = new EnumInfo(id, type, enumerators); + + return createType(info); +} + +extern "C" +PyObject* +IcePy_defineStruct(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + PyObject* meta; // Not currently used. + PyObject* members; + if(!PyArg_ParseTuple(args, STRCAST("sOOO"), &id, &type, &meta, &members)) + { + return 0; + } + + assert(PyType_Check(type)); + assert(PyTuple_Check(meta)); + assert(PyTuple_Check(members)); + + StructInfoPtr info = new StructInfo(id, type, members); + + return createType(info); +} + +extern "C" +PyObject* +IcePy_defineSequence(PyObject*, PyObject* args) +{ + char* id; + PyObject* meta; + PyObject* elementType; + if(!PyArg_ParseTuple(args, STRCAST("sOO"), &id, &meta, &elementType)) + { + return 0; + } + + SequenceInfoPtr info = new SequenceInfo(id, meta, elementType); + + return createType(info); +} + +extern "C" +PyObject* +IcePy_defineCustom(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + if(!PyArg_ParseTuple(args, STRCAST("sO"), &id, &type)) + { + return 0; + } + + CustomInfoPtr info = new CustomInfo(id, type); + + return createType(info); +} + +extern "C" +PyObject* +IcePy_defineDictionary(PyObject*, PyObject* args) +{ + char* id; + PyObject* meta; // Not currently used. + PyObject* keyType; + PyObject* valueType; + if(!PyArg_ParseTuple(args, STRCAST("sOOO"), &id, &meta, &keyType, &valueType)) + { + return 0; + } + + assert(PyTuple_Check(meta)); + + DictionaryInfoPtr info = new DictionaryInfo(id, keyType, valueType); + + return createType(info); +} + +extern "C" +PyObject* +IcePy_declareProxy(PyObject*, PyObject* args) +{ + char* id; + if(!PyArg_ParseTuple(args, STRCAST("s"), &id)) + { + return 0; + } + + string proxyId = id; + proxyId += "Prx"; + + ProxyInfoPtr info = lookupProxyInfo(proxyId); + if(!info) + { + info = new ProxyInfo(proxyId); + addProxyInfo(proxyId, info); + } + + Py_INCREF(info->typeObj.get()); + return info->typeObj.get(); +} + +extern "C" +PyObject* +IcePy_defineProxy(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + if(!PyArg_ParseTuple(args, STRCAST("sO"), &id, &type)) + { + return 0; + } + + assert(PyType_Check(type)); + + string proxyId = id; + proxyId += "Prx"; + + ProxyInfoPtr info = lookupProxyInfo(proxyId); + if(!info) + { + info = new ProxyInfo(proxyId); + addProxyInfo(proxyId, info); + } + + info->define(type); + + Py_INCREF(info->typeObj.get()); + return info->typeObj.get(); +} + +extern "C" +PyObject* +IcePy_declareClass(PyObject*, PyObject* args) +{ + char* id; + if(!PyArg_ParseTuple(args, STRCAST("s"), &id)) + { + return 0; + } + + ClassInfoPtr info = lookupClassInfo(id); + if(!info) + { + info = new ClassInfo(id); + addClassInfo(id, info); + } + + Py_INCREF(info->typeObj.get()); + return info->typeObj.get(); +} + +extern "C" +PyObject* +IcePy_defineClass(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + int compactId; + PyObject* meta; // Not currently used. + int isAbstract; + int preserve; + PyObject* base; + PyObject* interfaces; + PyObject* members; + if(!PyArg_ParseTuple(args, STRCAST("sOiOiiOOO"), &id, &type, &compactId, &meta, &isAbstract, &preserve, &base, + &interfaces, &members)) + { + return 0; + } + + assert(PyTuple_Check(meta)); + + // + // A ClassInfo object will already exist for this id if a forward declaration + // was encountered, or if the Slice definition is being reloaded. In the latter + // case, we act as if it hasn't been defined yet. + // + ClassInfoPtr info = lookupClassInfo(id); + if(!info || info->defined) + { + info = new ClassInfo(id); + addClassInfo(id, info); + } + + info->define(type, compactId, isAbstract ? true : false, preserve ? true : false, base, interfaces, members); + + CompactIdMap::iterator q = _compactIdMap.find(info->compactId); + if(q != _compactIdMap.end()) + { + _compactIdMap.erase(q); + } + _compactIdMap.insert(CompactIdMap::value_type(info->compactId, info)); + + Py_INCREF(info->typeObj.get()); + return info->typeObj.get(); +} + +extern "C" +PyObject* +IcePy_defineException(PyObject*, PyObject* args) +{ + char* id; + PyObject* type; + PyObject* meta; + int preserve; + PyObject* base; + PyObject* members; + if(!PyArg_ParseTuple(args, STRCAST("sOOiOO"), &id, &type, &meta, &preserve, &base, &members)) + { + return 0; + } + + assert(PyExceptionClass_Check(type)); + assert(PyTuple_Check(meta)); + assert(PyTuple_Check(members)); + + ExceptionInfoPtr info = new ExceptionInfo; + info->id = id; + + info->preserve = preserve ? true : false; + + if(base != Py_None) + { + info->base = ExceptionInfoPtr::dynamicCast(getException(base)); + assert(info->base); + } + + convertDataMembers(members, info->members, info->optionalMembers, true); + + info->usesClasses = false; + + // + // Only examine the required members to see if any use classes. + // + for(DataMemberList::iterator p = info->members.begin(); p != info->members.end(); ++p) + { + if(!info->usesClasses) + { + info->usesClasses = (*p)->type->usesClasses(); + } + } + + info->pythonType = type; + Py_INCREF(type); + + addExceptionInfo(id, info); + + return createException(info); +} + +extern "C" +PyObject* +IcePy_stringify(PyObject*, PyObject* args) +{ + PyObject* value; + PyObject* type; + if(!PyArg_ParseTuple(args, STRCAST("OO"), &value, &type)) + { + return 0; + } + + TypeInfoPtr info = getType(type); + assert(info); + + ostringstream ostr; + IceUtilInternal::Output out(ostr); + PrintObjectHistory history; + history.index = 0; + info->print(value, out, &history); + + string str = ostr.str(); + return createString(str); +} + +extern "C" +PyObject* +IcePy_stringifyException(PyObject*, PyObject* args) +{ + PyObject* value; + if(!PyArg_ParseTuple(args, STRCAST("O"), &value)) + { + return 0; + } + + PyObjectHandle iceType = PyObject_GetAttrString(value, STRCAST("_ice_type")); + assert(iceType.get()); + ExceptionInfoPtr info = getException(iceType.get()); + assert(info); + + ostringstream ostr; + IceUtilInternal::Output out(ostr); + info->print(value, out); + + string str = ostr.str(); + return createString(str); +} diff --git a/python/modules/IcePy/Types.h b/python/modules/IcePy/Types.h new file mode 100644 index 00000000000..9f26418b28d --- /dev/null +++ b/python/modules/IcePy/Types.h @@ -0,0 +1,646 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_TYPES_H +#define ICEPY_TYPES_H + +#include <Config.h> +#include <Util.h> +#include <Ice/Stream.h> +#include <IceUtil/OutputUtil.h> + +#include <set> + +namespace IcePy +{ + +class ExceptionInfo; +typedef IceUtil::Handle<ExceptionInfo> ExceptionInfoPtr; +typedef std::vector<ExceptionInfoPtr> ExceptionInfoList; + +class ClassInfo; +typedef IceUtil::Handle<ClassInfo> ClassInfoPtr; +typedef std::vector<ClassInfoPtr> ClassInfoList; + +// +// This class is raised as an exception when object marshaling needs to be aborted. +// +class AbortMarshaling +{ +}; + +typedef std::map<PyObject*, Ice::ObjectPtr> ObjectMap; + +class ObjectReader; +typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr; + +// +// This class keeps track of Python objects (instances of Slice classes +// and exceptions) that have preserved slices. +// +class SlicedDataUtil +{ +public: + + SlicedDataUtil(); + ~SlicedDataUtil(); + + void add(const ObjectReaderPtr&); + + void update(); + + static void setMember(PyObject*, const Ice::SlicedDataPtr&); + static Ice::SlicedDataPtr getMember(PyObject*, ObjectMap*); + +private: + + std::set<ObjectReaderPtr> _readers; + static PyObject* _slicedDataType; + static PyObject* _sliceInfoType; +}; + +struct PrintObjectHistory +{ + int index; + std::map<PyObject*, int> objects; +}; + +// +// The delayed nature of class unmarshaling in the Ice protocol requires us to +// handle unmarshaling using a callback strategy. An instance of UnmarshalCallback +// is supplied to each type's unmarshal() member function. For all types except +// classes, the callback is invoked with the unmarshaled value before unmarshal() +// returns. For class instances, however, the callback may not be invoked until +// the stream's finished() function is called. +// +class UnmarshalCallback : public IceUtil::Shared +{ +public: + + virtual ~UnmarshalCallback(); + + // + // The unmarshaled() member function receives the unmarshaled value. The + // last two arguments are the values passed to unmarshal() for use by + // UnmarshalCallback implementations. + // + virtual void unmarshaled(PyObject*, PyObject*, void*) = 0; +}; +typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr; + +// +// Base class for type information. +// +class TypeInfo : public UnmarshalCallback +{ +public: + + virtual std::string getId() const = 0; + + virtual bool validate(PyObject*) = 0; + + virtual bool variableLength() const = 0; + virtual int wireSize() const = 0; + virtual Ice::OptionalFormat optionalFormat() const = 0; + + virtual bool usesClasses() const; // Default implementation returns false. + + virtual void unmarshaled(PyObject*, PyObject*, void*); // Default implementation is assert(false). + + virtual void destroy(); + +protected: + + TypeInfo(); + +public: + + // + // The marshal and unmarshal functions can raise Ice exceptions, and may raise + // AbortMarshaling if an error occurs. + // + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0) = 0; + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0) = 0; + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*) = 0; +}; +typedef IceUtil::Handle<TypeInfo> TypeInfoPtr; + +// +// Primitive type information. +// +class PrimitiveInfo : public TypeInfo +{ +public: + + enum Kind + { + KindBool, + KindByte, + KindShort, + KindInt, + KindLong, + KindFloat, + KindDouble, + KindString + }; + + PrimitiveInfo(Kind); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + const Kind kind; +}; +typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr; + +// +// Enum information. +// +typedef std::map<Ice::Int, PyObjectHandle> EnumeratorMap; + +class EnumInfo : public TypeInfo +{ +public: + + EnumInfo(const std::string&, PyObject*, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + Ice::Int valueForEnumerator(PyObject*) const; + PyObject* enumeratorForValue(Ice::Int) const; + + const std::string id; + const PyObjectHandle pythonType; + const Ice::Int maxValue; + const EnumeratorMap enumerators; +}; +typedef IceUtil::Handle<EnumInfo> EnumInfoPtr; + +class DataMember : public UnmarshalCallback +{ +public: + + virtual void unmarshaled(PyObject*, PyObject*, void*); + + std::string name; + std::vector<std::string> metaData; + TypeInfoPtr type; + bool optional; + int tag; +}; +typedef IceUtil::Handle<DataMember> DataMemberPtr; +typedef std::vector<DataMemberPtr> DataMemberList; + +// +// Struct information. +// +class StructInfo : public TypeInfo +{ +public: + + StructInfo(const std::string&, PyObject*, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual bool usesClasses() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + + static PyObject* instantiate(PyObject*); + + const std::string id; + const DataMemberList members; + const PyObjectHandle pythonType; + +private: + + bool _variableLength; + int _wireSize; + PyObjectHandle _nullMarshalValue; +}; +typedef IceUtil::Handle<StructInfo> StructInfoPtr; + +// +// Sequence information. +// +class SequenceInfo : public TypeInfo +{ +public: + + SequenceInfo(const std::string&, PyObject*, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual bool usesClasses() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + +private: + + struct SequenceMapping : public UnmarshalCallback + { + enum Type { SEQ_DEFAULT, SEQ_TUPLE, SEQ_LIST }; + + SequenceMapping(Type); + SequenceMapping(const Ice::StringSeq&); + + static bool getType(const Ice::StringSeq&, Type&); + + virtual void unmarshaled(PyObject*, PyObject*, void*); + + PyObject* createContainer(int) const; + void setItem(PyObject*, int, PyObject*) const; + + Type type; + }; + typedef IceUtil::Handle<SequenceMapping> SequenceMappingPtr; + + PyObject* getSequence(const PrimitiveInfoPtr&, PyObject*); + void marshalPrimitiveSequence(const PrimitiveInfoPtr&, PyObject*, const Ice::OutputStreamPtr&); + void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, + PyObject*, void*, const SequenceMappingPtr&); + +public: + + const std::string id; + const SequenceMappingPtr mapping; + const TypeInfoPtr elementType; +}; +typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr; + +// +// Custom information. +// +class CustomInfo : public TypeInfo +{ +public: + + CustomInfo(const std::string&, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual bool usesClasses() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + + const std::string id; + const PyObjectHandle pythonType; +}; +typedef IceUtil::Handle<CustomInfo> CustomInfoPtr; + +// +// Dictionary information. +// +class DictionaryInfo : public TypeInfo +{ +public: + + DictionaryInfo(const std::string&, PyObject*, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual bool usesClasses() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + virtual void unmarshaled(PyObject*, PyObject*, void*); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + + class KeyCallback : public UnmarshalCallback + { + public: + + virtual void unmarshaled(PyObject*, PyObject*, void*); + + PyObjectHandle key; + }; + typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr; + + std::string id; + TypeInfoPtr keyType; + TypeInfoPtr valueType; + +private: + + bool _variableLength; + int _wireSize; +}; +typedef IceUtil::Handle<DictionaryInfo> DictionaryInfoPtr; + +typedef std::vector<TypeInfoPtr> TypeInfoList; + +class ClassInfo : public TypeInfo +{ +public: + + ClassInfo(const std::string&); + + void define(PyObject*, int, bool, bool, PyObject*, PyObject*, PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual bool usesClasses() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + + void printMembers(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + const std::string id; + const Ice::Int compactId; + const bool isAbstract; + const bool preserve; + const ClassInfoPtr base; + const ClassInfoList interfaces; + const DataMemberList members; + const DataMemberList optionalMembers; + const PyObjectHandle pythonType; + const PyObjectHandle typeObj; + const bool defined; +}; + +// +// Proxy information. +// +class ProxyInfo : public TypeInfo +{ +public: + + ProxyInfo(const std::string&); + + void define(PyObject*); + + virtual std::string getId() const; + + virtual bool validate(PyObject*); + + virtual bool variableLength() const; + virtual int wireSize() const; + virtual Ice::OptionalFormat optionalFormat() const; + + virtual void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*, bool, const Ice::StringSeq* = 0); + virtual void unmarshal(const Ice::InputStreamPtr&, const UnmarshalCallbackPtr&, PyObject*, void*, bool, + const Ice::StringSeq* = 0); + + virtual void print(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + virtual void destroy(); + + const std::string id; + const PyObjectHandle pythonType; + const PyObjectHandle typeObj; +}; +typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr; + +// +// Exception information. +// +class ExceptionInfo : public IceUtil::Shared +{ +public: + + void marshal(PyObject*, const Ice::OutputStreamPtr&, ObjectMap*); + PyObject* unmarshal(const Ice::InputStreamPtr&); + + void print(PyObject*, IceUtilInternal::Output&); + void printMembers(PyObject*, IceUtilInternal::Output&, PrintObjectHistory*); + + std::string id; + bool preserve; + ExceptionInfoPtr base; + DataMemberList members; + DataMemberList optionalMembers; + bool usesClasses; + PyObjectHandle pythonType; + +private: + + void writeMembers(PyObject*, const Ice::OutputStreamPtr&, const DataMemberList&, ObjectMap*) const; +}; + +// +// ObjectWriter wraps a Python object for marshaling. +// +class ObjectWriter : public Ice::ObjectWriter +{ +public: + + ObjectWriter(PyObject*, ObjectMap*); + ~ObjectWriter(); + + virtual void ice_preMarshal(); + + virtual void write(const Ice::OutputStreamPtr&) const; + +private: + + void writeMembers(const Ice::OutputStreamPtr&, const DataMemberList&) const; + + PyObject* _object; + ObjectMap* _map; + ClassInfoPtr _info; +}; + +// +// ObjectReader unmarshals the state of an Ice object. +// +class ObjectReader : public Ice::ObjectReader +{ +public: + + ObjectReader(PyObject*, const ClassInfoPtr&); + ~ObjectReader(); + + virtual void ice_postUnmarshal(); + + virtual void read(const Ice::InputStreamPtr&); + + virtual ClassInfoPtr getInfo() const; + + PyObject* getObject() const; // Borrowed reference. + + Ice::SlicedDataPtr getSlicedData() const; + +private: + + PyObject* _object; + ClassInfoPtr _info; + Ice::SlicedDataPtr _slicedData; +}; + +// +// ExceptionWriter wraps a Python user exception for marshaling. +// +class ExceptionWriter : public Ice::UserExceptionWriter +{ +public: + + ExceptionWriter(const Ice::CommunicatorPtr&, const PyObjectHandle&, const ExceptionInfoPtr& = 0); + ~ExceptionWriter() throw(); + + virtual void write(const Ice::OutputStreamPtr&) const; + virtual bool usesClasses() const; + + virtual std::string ice_name() const; + virtual Ice::UserException* ice_clone() const; + virtual void ice_throw() const; + +private: + + PyObjectHandle _ex; + ExceptionInfoPtr _info; + ObjectMap _objects; +}; + +// +// ExceptionReader creates a Python user exception and unmarshals it. +// +class ExceptionReader : public Ice::UserExceptionReader +{ +public: + + ExceptionReader(const Ice::CommunicatorPtr&, const ExceptionInfoPtr&); + ~ExceptionReader() throw(); + + virtual void read(const Ice::InputStreamPtr&) const; + virtual bool usesClasses() const; + + virtual std::string ice_name() const; + virtual Ice::UserException* ice_clone() const; + virtual void ice_throw() const; + + PyObject* getException() const; // Borrowed reference. + + Ice::SlicedDataPtr getSlicedData() const; + +private: + + ExceptionInfoPtr _info; + PyObjectHandle _ex; + Ice::SlicedDataPtr _slicedData; +}; + +class IdResolver : public Ice::CompactIdResolver +{ +public: + + virtual ::std::string resolve(Ice::Int) const; +}; + +ClassInfoPtr lookupClassInfo(const std::string&); +ExceptionInfoPtr lookupExceptionInfo(const std::string&); + +extern PyObject* Unset; + +bool initTypes(PyObject*); + +PyObject* createType(const TypeInfoPtr&); +TypeInfoPtr getType(PyObject*); + +PyObject* createException(const ExceptionInfoPtr&); +ExceptionInfoPtr getException(PyObject*); + +} + +extern "C" PyObject* IcePy_defineEnum(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineStruct(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineSequence(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineCustom(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineDictionary(PyObject*, PyObject*); +extern "C" PyObject* IcePy_declareProxy(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineProxy(PyObject*, PyObject*); +extern "C" PyObject* IcePy_declareClass(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineClass(PyObject*, PyObject*); +extern "C" PyObject* IcePy_defineException(PyObject*, PyObject*); +extern "C" PyObject* IcePy_stringify(PyObject*, PyObject*); +extern "C" PyObject* IcePy_stringifyException(PyObject*, PyObject*); + +#endif diff --git a/python/modules/IcePy/Util.cpp b/python/modules/IcePy/Util.cpp new file mode 100644 index 00000000000..74869df7121 --- /dev/null +++ b/python/modules/IcePy/Util.cpp @@ -0,0 +1,1163 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifdef _WIN32 +# include <IceUtil/Config.h> +#endif +#include <Util.h> +#include <IceUtil/DisableWarnings.h> +#include <Ice/LocalException.h> +#include <Ice/Protocol.h> +#include <IceUtil/UUID.h> +#include <Slice/PythonUtil.h> +#include <compile.h> +#include <frameobject.h> + +using namespace std; +using namespace Slice::Python; + +namespace IcePy +{ + +bool +checkIsInstance(PyObject* p, const char* type) +{ + PyObject* pyType = lookupType(type); + return PyObject_IsInstance(p, pyType) == 1; +} + +template<typename T> bool +setVersion(PyObject* p, const T& version, const char* type) +{ + assert(checkIsInstance(p, type)); + + PyObjectHandle major = PyLong_FromLong(version.major); + PyObjectHandle minor = PyLong_FromLong(version.minor); + if(!major.get() || !minor.get()) + { + return false; + } + if(PyObject_SetAttrString(p, STRCAST("major"), major.get()) < 0 || + PyObject_SetAttrString(p, STRCAST("minor"), minor.get()) < 0) + { + return false; + } + return true; +} + +template<typename T> bool +getVersion(PyObject* p, T& v, const char* type) +{ + assert(checkIsInstance(p, type)); + PyObjectHandle major = PyObject_GetAttrString(p, STRCAST("major")); + PyObjectHandle minor = PyObject_GetAttrString(p, STRCAST("minor")); + if(major.get()) + { + major = PyNumber_Long(major.get()); + if(!major.get()) + { + PyErr_Format(PyExc_ValueError, STRCAST("version major must be a numeric value")); + return false; + } + long m = PyLong_AsLong(major.get()); + if(m < 0 || m > 255) + { + PyErr_Format(PyExc_ValueError, STRCAST("version major must be a value between 0 and 255")); + return false; + } + v.major = static_cast<Ice::Byte>(m); + } + if(minor.get()) + { + major = PyNumber_Long(minor.get()); + if(!minor.get()) + { + PyErr_Format(PyExc_ValueError, STRCAST("version minor must be a numeric value")); + return false; + } + long m = PyLong_AsLong(minor.get()); + if(m < 0 || m > 255) + { + PyErr_Format(PyExc_ValueError, STRCAST("version minor must be a value between 0 and 255")); + return false; + } + v.minor = static_cast<Ice::Byte>(m); + } + return true; +} + +template<typename T> PyObject* +createVersion(const T& version, const char* type) +{ + PyObject* versionType = lookupType(type); + + PyObjectHandle obj = PyObject_CallObject(versionType, 0); + if(!obj.get()) + { + return 0; + } + + if(!setVersion<T>(obj.get(), version, type)) + { + return 0; + } + + return obj.release(); +} + +template<typename T> PyObject* +versionToString(PyObject* args, const char* type) +{ + PyObject* versionType = IcePy::lookupType(type); + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O!"), versionType, &p)) + { + return NULL; + } + + T v; + if(!getVersion<T>(p, v, type)) + { + return NULL; + } + + string s; + try + { + s = IceInternal::versionToString<T>(v); + } + catch(const Ice::Exception& ex) + { + IcePy::setPythonException(ex); + return NULL; + } + return createString(s); +} + +template<typename T> PyObject* +stringToVersion(PyObject* args, const char* type) +{ + char* str; + if(!PyArg_ParseTuple(args, STRCAST("s"), &str)) + { + return NULL; + } + + T v; + try + { + v = IceInternal::stringToVersion<T>(str); + } + catch(const Ice::Exception& ex) + { + IcePy::setPythonException(ex); + return NULL; + } + + return createVersion<T>(v, type); +} + +char Ice_ProtocolVersion[] = "Ice.ProtocolVersion"; +char Ice_EncodingVersion[] = "Ice.EncodingVersion"; + +} + +string +IcePy::getString(PyObject* p) +{ + assert(p == Py_None || checkString(p)); + + string str; + if(p != Py_None) + { +#if PY_VERSION_HEX >= 0x03000000 + PyObjectHandle bytes = PyUnicode_AsUTF8String(p); + if(bytes.get()) + { + char* s; + Py_ssize_t sz; + PyBytes_AsStringAndSize(bytes.get(), &s, &sz); + str.assign(s, sz); + } +#else + str.assign(PyString_AS_STRING(p), PyString_GET_SIZE(p)); +#endif + } + return str; +} + +bool +IcePy::getStringArg(PyObject* p, const string& arg, string& val) +{ + if(checkString(p)) + { + val = getString(p); + } + else if(p != Py_None) + { + string funcName = getFunction(); + PyErr_Format(PyExc_ValueError, STRCAST("%s expects a string for argument '%s'"), funcName.c_str(), arg.c_str()); + return false; + } + return true; +} + +string +IcePy::getFunction() +{ + // + // Get name of current function. + // + PyFrameObject *f = PyThreadState_GET()->frame; + PyObjectHandle code = PyObject_GetAttrString(reinterpret_cast<PyObject*>(f), STRCAST("f_code")); + assert(code.get()); + PyObjectHandle func = PyObject_GetAttrString(code.get(), STRCAST("co_name")); + assert(func.get()); + return getString(func.get()); +} + +IcePy::PyObjectHandle::PyObjectHandle(PyObject* p) : + _p(p) +{ +} + +IcePy::PyObjectHandle::PyObjectHandle(const PyObjectHandle& p) : + _p(p._p) +{ + Py_XINCREF(_p); +} + +IcePy::PyObjectHandle::~PyObjectHandle() +{ + if(_p) + { + Py_DECREF(_p); + } +} + +void +IcePy::PyObjectHandle::operator=(PyObject* p) +{ + if(_p) + { + Py_DECREF(_p); + } + _p = p; +} + +void +IcePy::PyObjectHandle::operator=(const PyObjectHandle& p) +{ + Py_XDECREF(_p); + _p = p._p; + Py_XINCREF(_p); +} + +PyObject* +IcePy::PyObjectHandle::get() const +{ + return _p; +} + +PyObject* +IcePy::PyObjectHandle::release() +{ + PyObject* result = _p; + _p = 0; + return result; +} + +IcePy::PyException::PyException() +{ + PyObject* type; + PyObject* e; + PyObject* tb; + + PyErr_Fetch(&type, &e, &tb); // PyErr_Fetch clears the exception. + PyErr_NormalizeException(&type, &e, &tb); + + _type = type; + ex = e; + _tb = tb; +} + +IcePy::PyException::PyException(PyObject* p) +{ + ex = p; + Py_XINCREF(p); +} + +void +IcePy::PyException::raise() +{ + assert(ex.get()); + + PyObject* userExceptionType = lookupType("Ice.UserException"); + PyObject* localExceptionType = lookupType("Ice.LocalException"); + + if(PyObject_IsInstance(ex.get(), userExceptionType)) + { + Ice::UnknownUserException e(__FILE__, __LINE__); + string tb = getTraceback(); + if(!tb.empty()) + { + e.unknown = tb; + } + else + { + PyObjectHandle name = PyObject_CallMethod(ex.get(), STRCAST("ice_name"), 0); + PyErr_Clear(); + if(!name.get()) + { + e.unknown = getTypeName(); + } + else + { + e.unknown = getString(name.get()); + } + } + throw e; + } + else if(PyObject_IsInstance(ex.get(), localExceptionType)) + { + raiseLocalException(); + } + else + { + Ice::UnknownException e(__FILE__, __LINE__); + string tb = getTraceback(); + if(!tb.empty()) + { + e.unknown = tb; + } + else + { + ostringstream ostr; + + ostr << getTypeName(); + + IcePy::PyObjectHandle msg = PyObject_Str(ex.get()); + if(msg.get()) + { + string s = getString(msg.get()); + if(!s.empty()) + { + ostr << ": " << s; + } + } + + e.unknown = ostr.str(); + } + throw e; + } +} + +void +IcePy::PyException::checkSystemExit() +{ + if(PyObject_IsInstance(ex.get(), PyExc_SystemExit)) + { + handleSystemExit(ex.get()); // Does not return. + } +} + +void +IcePy::PyException::raiseLocalException() +{ + string typeName = getTypeName(); + + try + { + if(typeName == "Ice.ObjectNotExistException") + { + throw Ice::ObjectNotExistException(__FILE__, __LINE__); + } + else if(typeName == "Ice.OperationNotExistException") + { + throw Ice::OperationNotExistException(__FILE__, __LINE__); + } + else if(typeName == "Ice.FacetNotExistException") + { + throw Ice::FacetNotExistException(__FILE__, __LINE__); + } + else if(typeName == "Ice.RequestFailedException") + { + throw Ice::RequestFailedException(__FILE__, __LINE__); + } + } + catch(Ice::RequestFailedException& e) + { + IcePy::PyObjectHandle member; + member = PyObject_GetAttrString(ex.get(), STRCAST("id")); + if(member.get() && IcePy::checkIdentity(member.get())) + { + IcePy::getIdentity(member.get(), e.id); + } + member = PyObject_GetAttrString(ex.get(), STRCAST("facet")); + if(member.get() && checkString(member.get())) + { + e.facet = getString(member.get()); + } + member = PyObject_GetAttrString(ex.get(), STRCAST("operation")); + if(member.get() && checkString(member.get())) + { + e.operation = getString(member.get()); + } + throw; + } + + try + { + if(typeName == "Ice.UnknownLocalException") + { + throw Ice::UnknownLocalException(__FILE__, __LINE__); + } + else if(typeName == "Ice.UnknownUserException") + { + throw Ice::UnknownUserException(__FILE__, __LINE__); + } + else if(typeName == "Ice.UnknownException") + { + throw Ice::UnknownException(__FILE__, __LINE__); + } + } + catch(Ice::UnknownException& e) + { + IcePy::PyObjectHandle member; + member = PyObject_GetAttrString(ex.get(), STRCAST("unknown")); + if(member.get() && checkString(member.get())) + { + e.unknown = getString(member.get()); + } + throw; + } + + Ice::UnknownLocalException e(__FILE__, __LINE__); + string tb = getTraceback(); + if(!tb.empty()) + { + e.unknown = tb; + } + else + { + e.unknown = typeName; + } + throw e; +} + +string +IcePy::PyException::getTraceback() +{ + if(!_tb.get()) + { + return string(); + } + + // + // We need the equivalent of the following Python code: + // + // import traceback + // list = traceback.format_exception(type, ex, tb) + // + PyObjectHandle str = createString("traceback"); + PyObjectHandle mod = PyImport_Import(str.get()); + assert(mod.get()); // Unable to import traceback module - Python installation error? + PyObject* d = PyModule_GetDict(mod.get()); + PyObject* func = PyDict_GetItemString(d, "format_exception"); + assert(func); // traceback.format_exception must be present. + PyObjectHandle args = Py_BuildValue("(OOO)", _type.get(), ex.get(), _tb.get()); + PyObjectHandle list = PyObject_CallObject(func, args.get()); + + string result; + for(Py_ssize_t i = 0; i < PyList_GET_SIZE(list.get()); ++i) + { + string s = getString(PyList_GetItem(list.get(), i)); + result += s; + } + + return result; +} + +string +IcePy::PyException::getTypeName() +{ + PyObject* cls = reinterpret_cast<PyObject*>(ex.get()->ob_type); + PyObjectHandle name = PyObject_GetAttrString(cls, "__name__"); + assert(name.get()); + PyObjectHandle mod = PyObject_GetAttrString(cls, "__module__"); + assert(mod.get()); + string result = getString(mod.get()); + result += "."; + result += getString(name.get()); + return result; +} + +bool +IcePy::listToStringSeq(PyObject* l, Ice::StringSeq& seq) +{ + assert(PyList_Check(l)); + + Py_ssize_t sz = PyList_GET_SIZE(l); + for(Py_ssize_t i = 0; i < sz; ++i) + { + PyObject* item = PyList_GET_ITEM(l, i); + if(!item) + { + return false; + } + string str; + if(checkString(item)) + { + str = getString(item); + } + else if(item != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("list element must be a string")); + return false; + } + seq.push_back(str); + } + + return true; +} + +bool +IcePy::stringSeqToList(const Ice::StringSeq& seq, PyObject* l) +{ + assert(PyList_Check(l)); + + for(Ice::StringSeq::const_iterator p = seq.begin(); p != seq.end(); ++p) + { + PyObject* str = Py_BuildValue(STRCAST("s"), p->c_str()); + if(!str) + { + Py_DECREF(l); + return false; + } + int status = PyList_Append(l, str); + Py_DECREF(str); // Give ownership to the list. + if(status < 0) + { + Py_DECREF(l); + return false; + } + } + + return true; +} + +bool +IcePy::tupleToStringSeq(PyObject* t, Ice::StringSeq& seq) +{ + assert(PyTuple_Check(t)); + + int sz = static_cast<int>(PyTuple_GET_SIZE(t)); + for(int i = 0; i < sz; ++i) + { + PyObject* item = PyTuple_GET_ITEM(t, i); + if(!item) + { + return false; + } + string str; + if(checkString(item)) + { + str = getString(item); + } + else if(item != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("tuple element must be a string")); + return false; + } + seq.push_back(str); + } + + return true; +} + +bool +IcePy::dictionaryToContext(PyObject* dict, Ice::Context& context) +{ + assert(PyDict_Check(dict)); + + Py_ssize_t pos = 0; + PyObject* key; + PyObject* value; + while(PyDict_Next(dict, &pos, &key, &value)) + { + string keystr; + if(checkString(key)) + { + keystr = getString(key); + } + else if(key != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("context key must be a string")); + return false; + } + + string valuestr; + if(checkString(value)) + { + valuestr = getString(value); + } + else if(value != Py_None) + { + PyErr_Format(PyExc_ValueError, STRCAST("context value must be a string")); + return false; + } + + context.insert(Ice::Context::value_type(keystr, valuestr)); + } + + return true; +} + +bool +IcePy::contextToDictionary(const Ice::Context& ctx, PyObject* dict) +{ + assert(PyDict_Check(dict)); + + for(Ice::Context::const_iterator p = ctx.begin(); p != ctx.end(); ++p) + { + PyObjectHandle key = createString(p->first); + PyObjectHandle value = createString(p->second); + if(!key.get() || !value.get()) + { + return false; + } + if(PyDict_SetItem(dict, key.get(), value.get()) < 0) + { + return false; + } + } + + return true; +} + +PyObject* +IcePy::lookupType(const string& typeName) +{ + string::size_type dot = typeName.rfind('.'); + assert(dot != string::npos); + string moduleName = typeName.substr(0, dot); + string name = typeName.substr(dot + 1); + + // + // First search for the module in sys.modules. + // + PyObject* sysModules = PyImport_GetModuleDict(); + assert(sysModules); + + PyObject* module = PyDict_GetItemString(sysModules, const_cast<char*>(moduleName.c_str())); + PyObject* dict; + if(!module) + { + // + // Not found, so we need to import the module. + // + PyObjectHandle h = PyImport_ImportModule(const_cast<char*>(moduleName.c_str())); + if(!h.get()) + { + return 0; + } + + dict = PyModule_GetDict(h.get()); + } + else + { + dict = PyModule_GetDict(module); + } + + assert(dict); + return PyDict_GetItemString(dict, const_cast<char*>(name.c_str())); +} + +PyObject* +IcePy::createExceptionInstance(PyObject* type) +{ + assert(PyExceptionClass_Check(type)); + IcePy::PyObjectHandle args = PyTuple_New(0); + if(!args.get()) + { + return 0; + } + return PyEval_CallObject(type, args.get()); +} + +static void +convertLocalException(const Ice::LocalException& ex, PyObject* p) +{ + // + // Transfer data members from Ice exception to Python exception. + // + try + { + ex.ice_throw(); + } + catch(const Ice::InitializationException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + } + catch(const Ice::PluginInitializationException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + } + catch(const Ice::AlreadyRegisteredException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createString(e.kindOfObject); + PyObject_SetAttrString(p, STRCAST("kindOfObject"), m.get()); + m = IcePy::createString(e.id); + PyObject_SetAttrString(p, STRCAST("id"), m.get()); + } + catch(const Ice::NotRegisteredException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createString(e.kindOfObject); + PyObject_SetAttrString(p, STRCAST("kindOfObject"), m.get()); + m = IcePy::createString(e.id); + PyObject_SetAttrString(p, STRCAST("id"), m.get()); + } + catch(const Ice::TwowayOnlyException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.operation); + PyObject_SetAttrString(p, STRCAST("operation"), m.get()); + } + catch(const Ice::UnknownException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.unknown); + PyObject_SetAttrString(p, STRCAST("unknown"), m.get()); + } + catch(const Ice::ObjectAdapterDeactivatedException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.name); + PyObject_SetAttrString(p, STRCAST("name"), m.get()); + } + catch(const Ice::ObjectAdapterIdInUseException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.id); + PyObject_SetAttrString(p, STRCAST("id"), m.get()); + } + catch(const Ice::NoEndpointException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.proxy); + PyObject_SetAttrString(p, STRCAST("proxy"), m.get()); + } + catch(const Ice::EndpointParseException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.str); + PyObject_SetAttrString(p, STRCAST("str"), m.get()); + } + catch(const Ice::IdentityParseException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.str); + PyObject_SetAttrString(p, STRCAST("str"), m.get()); + } + catch(const Ice::ProxyParseException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.str); + PyObject_SetAttrString(p, STRCAST("str"), m.get()); + } + catch(const Ice::IllegalIdentityException& e) + { + IcePy::PyObjectHandle m = IcePy::createIdentity(e.id); + PyObject_SetAttrString(p, STRCAST("id"), m.get()); + } + catch(const Ice::RequestFailedException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createIdentity(e.id); + PyObject_SetAttrString(p, STRCAST("id"), m.get()); + m = IcePy::createString(e.facet); + PyObject_SetAttrString(p, STRCAST("facet"), m.get()); + m = IcePy::createString(e.operation); + PyObject_SetAttrString(p, STRCAST("operation"), m.get()); + } + catch(const Ice::FileException& e) + { + IcePy::PyObjectHandle m = PyLong_FromLong(e.error); + PyObject_SetAttrString(p, STRCAST("error"), m.get()); + m = IcePy::createString(e.path); + PyObject_SetAttrString(p, STRCAST("path"), m.get()); + } + catch(const Ice::SyscallException& e) // This must appear after all subclasses of SyscallException. + { + IcePy::PyObjectHandle m = PyLong_FromLong(e.error); + PyObject_SetAttrString(p, STRCAST("error"), m.get()); + } + catch(const Ice::DNSException& e) + { + IcePy::PyObjectHandle m; + m = PyLong_FromLong(e.error); + PyObject_SetAttrString(p, STRCAST("error"), m.get()); + m = IcePy::createString(e.host); + PyObject_SetAttrString(p, STRCAST("host"), m.get()); + } + catch(const Ice::UnsupportedProtocolException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createProtocolVersion(e.bad); + PyObject_SetAttrString(p, STRCAST("bad"), m.get()); + m = IcePy::createProtocolVersion(e.supported); + PyObject_SetAttrString(p, STRCAST("supported"), m.get()); + } + catch(const Ice::UnsupportedEncodingException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createEncodingVersion(e.bad); + PyObject_SetAttrString(p, STRCAST("bad"), m.get()); + m = IcePy::createEncodingVersion(e.supported); + PyObject_SetAttrString(p, STRCAST("supported"), m.get()); + } + catch(const Ice::NoObjectFactoryException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + m = IcePy::createString(e.type); + PyObject_SetAttrString(p, STRCAST("type"), m.get()); + } + catch(const Ice::UnexpectedObjectException& e) + { + IcePy::PyObjectHandle m; + m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + m = IcePy::createString(e.type); + PyObject_SetAttrString(p, STRCAST("type"), m.get()); + m = IcePy::createString(e.expectedType); + PyObject_SetAttrString(p, STRCAST("expectedType"), m.get()); + } + catch(const Ice::ProtocolException& e) // This must appear after all subclasses of ProtocolException. + { + IcePy::PyObjectHandle m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + } + catch(const Ice::FeatureNotSupportedException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.unsupportedFeature); + PyObject_SetAttrString(p, STRCAST("unsupportedFeature"), m.get()); + } + catch(const Ice::SecurityException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + } + catch(const Ice::IllegalServantException& e) + { + IcePy::PyObjectHandle m = IcePy::createString(e.reason); + PyObject_SetAttrString(p, STRCAST("reason"), m.get()); + } + catch(const Ice::LocalException&) + { + // + // Nothing to do. + // + } +} + +PyObject* +IcePy::convertException(const Ice::Exception& ex) +{ + PyObjectHandle p; + PyObject* type; + + ostringstream ostr; + ostr << ex; + string str = ostr.str(); + + try + { + ex.ice_throw(); + } + catch(const Ice::LocalException& e) + { + type = lookupType(scopedToName(e.ice_name())); + if(type) + { + p = createExceptionInstance(type); + if(p.get()) + { + convertLocalException(e, p.get()); + } + } + else + { + type = lookupType("Ice.UnknownLocalException"); + assert(type); + p = createExceptionInstance(type); + if(p.get()) + { + PyObjectHandle s = createString(str); + PyObject_SetAttrString(p.get(), STRCAST("unknown"), s.get()); + } + } + } + catch(const Ice::UserException&) + { + type = lookupType("Ice.UnknownUserException"); + assert(type); + p = createExceptionInstance(type); + if(p.get()) + { + PyObjectHandle s = createString(str); + PyObject_SetAttrString(p.get(), STRCAST("unknown"), s.get()); + } + } + catch(const Ice::Exception&) + { + type = lookupType("Ice.UnknownException"); + assert(type); + p = createExceptionInstance(type); + if(p.get()) + { + PyObjectHandle s = createString(str); + PyObject_SetAttrString(p.get(), STRCAST("unknown"), s.get()); + } + } + + return p.release(); +} + +void +IcePy::setPythonException(const Ice::Exception& ex) +{ + PyObjectHandle p = convertException(ex); + if(p.get()) + { + setPythonException(p.get()); + } +} + +void +IcePy::setPythonException(PyObject* ex) +{ + // + // PyErr_Restore steals references to the type and exception. + // + PyObject* type = PyObject_Type(ex); + assert(type); + Py_INCREF(ex); + PyErr_Restore(type, ex, 0); +} + +void +IcePy::throwPythonException() +{ + PyException ex; + ex.raise(); +} + +void +IcePy::handleSystemExit(PyObject* ex) +{ + // + // This code is similar to handle_system_exit in pythonrun.c. + // + PyObjectHandle code; + if(PyExceptionInstance_Check(ex)) + { + code = PyObject_GetAttrString(ex, STRCAST("code")); + } + else + { + code = ex; + Py_INCREF(ex); + } + + int status; + if(PyLong_Check(code.get())) + { + status = static_cast<int>(PyLong_AsLong(code.get())); + } + else + { + PyObject_Print(code.get(), stderr, Py_PRINT_RAW); + PySys_WriteStderr(STRCAST("\n")); + status = 1; + } + + code = 0; + Py_Exit(status); +} + +PyObject* +IcePy::createIdentity(const Ice::Identity& ident) +{ + PyObject* identityType = lookupType("Ice.Identity"); + + PyObjectHandle obj = PyObject_CallObject(identityType, 0); + if(!obj.get()) + { + return 0; + } + + if(!setIdentity(obj.get(), ident)) + { + return 0; + } + + return obj.release(); +} + +bool +IcePy::checkIdentity(PyObject* p) +{ + PyObject* identityType = lookupType("Ice.Identity"); + return PyObject_IsInstance(p, identityType) == 1; +} + +bool +IcePy::setIdentity(PyObject* p, const Ice::Identity& ident) +{ + assert(checkIdentity(p)); + PyObjectHandle name = createString(ident.name); + PyObjectHandle category = createString(ident.category); + if(!name.get() || !category.get()) + { + return false; + } + if(PyObject_SetAttrString(p, STRCAST("name"), name.get()) < 0 || + PyObject_SetAttrString(p, STRCAST("category"), category.get()) < 0) + { + return false; + } + return true; +} + +bool +IcePy::getIdentity(PyObject* p, Ice::Identity& ident) +{ + assert(checkIdentity(p)); + PyObjectHandle name = PyObject_GetAttrString(p, STRCAST("name")); + PyObjectHandle category = PyObject_GetAttrString(p, STRCAST("category")); + if(name.get()) + { + if(!checkString(name.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("identity name must be a string")); + return false; + } + ident.name = getString(name.get()); + } + if(category.get()) + { + if(!checkString(category.get())) + { + PyErr_Format(PyExc_ValueError, STRCAST("identity category must be a string")); + return false; + } + ident.category = getString(category.get()); + } + return true; +} + +PyObject* +IcePy::createProtocolVersion(const Ice::ProtocolVersion& v) +{ + return createVersion<Ice::ProtocolVersion>(v, Ice_ProtocolVersion); +} + +PyObject* +IcePy::createEncodingVersion(const Ice::EncodingVersion& v) +{ + return createVersion<Ice::EncodingVersion>(v, Ice_EncodingVersion); +} + +bool +IcePy::getEncodingVersion(PyObject* args, Ice::EncodingVersion& v) +{ + PyObject* versionType = IcePy::lookupType(Ice_EncodingVersion); + PyObject* p; + if(!PyArg_ParseTuple(args, STRCAST("O!"), versionType, &p)) + { + return false; + } + + if(!getVersion<Ice::EncodingVersion>(p, v, Ice_EncodingVersion)) + { + return false; + } + + return true; +} + +extern "C" +PyObject* +IcePy_stringVersion(PyObject* /*self*/) +{ + string s = ICE_STRING_VERSION; + return IcePy::createString(s); +} + +extern "C" +PyObject* +IcePy_intVersion(PyObject* /*self*/) +{ + return PyLong_FromLong(ICE_INT_VERSION); +} + +extern "C" +PyObject* +IcePy_currentProtocol(PyObject* /*self*/) +{ + return IcePy::createProtocolVersion(Ice::currentProtocol); +} + +extern "C" +PyObject* +IcePy_currentProtocolEncoding(PyObject* /*self*/) +{ + return IcePy::createEncodingVersion(Ice::currentProtocolEncoding); +} + +extern "C" +PyObject* +IcePy_currentEncoding(PyObject* /*self*/) +{ + return IcePy::createEncodingVersion(Ice::currentEncoding); +} + +extern "C" +PyObject* +IcePy_protocolVersionToString(PyObject* /*self*/, PyObject* args) +{ + return IcePy::versionToString<Ice::ProtocolVersion>(args, IcePy::Ice_ProtocolVersion); +} + +extern "C" +PyObject* +IcePy_stringToProtocolVersion(PyObject* /*self*/, PyObject* args) +{ + return IcePy::stringToVersion<Ice::ProtocolVersion>(args, IcePy::Ice_ProtocolVersion); +} + +extern "C" +PyObject* +IcePy_encodingVersionToString(PyObject* /*self*/, PyObject* args) +{ + return IcePy::versionToString<Ice::EncodingVersion>(args, IcePy::Ice_EncodingVersion); +} + +extern "C" +PyObject* +IcePy_stringToEncodingVersion(PyObject* /*self*/, PyObject* args) +{ + return IcePy::stringToVersion<Ice::EncodingVersion>(args, IcePy::Ice_EncodingVersion); +} + +extern "C" +PyObject* +IcePy_generateUUID(PyObject* /*self*/) +{ + string uuid = IceUtil::generateUUID(); + return IcePy::createString(uuid); +} diff --git a/python/modules/IcePy/Util.h b/python/modules/IcePy/Util.h new file mode 100644 index 00000000000..94f8d1b813d --- /dev/null +++ b/python/modules/IcePy/Util.h @@ -0,0 +1,264 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef ICEPY_UTIL_H +#define ICEPY_UTIL_H + +#include <Config.h> +#include <Ice/BuiltinSequences.h> +#include <Ice/Current.h> +#include <Ice/Exception.h> + +// +// These macros replace Py_RETURN_FALSE and Py_RETURN TRUE. We use these +// instead of the standard ones in order to avoid GCC warnings about +// strict aliasing and type punning. +// +#define PyRETURN_FALSE return Py_INCREF(getFalse()), getFalse() +#define PyRETURN_TRUE return Py_INCREF(getTrue()), getTrue() + +#define PyRETURN_BOOL(b) if(b) PyRETURN_TRUE; else PyRETURN_FALSE + +namespace IcePy +{ + +// +// This should be used instead of Py_False to avoid GCC compiler warnings. +// +inline PyObject* getFalse() +{ +#if PY_VERSION_HEX >= 0x03000000 + PyLongObject* i = &_Py_FalseStruct; + return reinterpret_cast<PyObject*>(i); +#else + PyIntObject* i = &_Py_ZeroStruct; + return reinterpret_cast<PyObject*>(i); +#endif +} + +// +// This should be used instead of Py_True to avoid GCC compiler warnings. +// +inline PyObject* getTrue() +{ +#if PY_VERSION_HEX >= 0x03000000 + PyLongObject* i = &_Py_TrueStruct; + return reinterpret_cast<PyObject*>(i); +#else + PyIntObject* i = &_Py_TrueStruct; + return reinterpret_cast<PyObject*>(i); +#endif +} + +// +// Create a string object. +// +inline PyObject* createString(const std::string& str) +{ +#if PY_VERSION_HEX >= 0x03000000 + // + // PyUnicode_FromStringAndSize interprets the argument as UTF-8. + // + return PyUnicode_FromStringAndSize(str.c_str(), static_cast<Py_ssize_t>(str.size())); +#else + return PyString_FromStringAndSize(str.c_str(), static_cast<Py_ssize_t>(str.size())); +#endif +} + +// +// Obtain a string from a string object; None is also legal. +// +std::string getString(PyObject*); + +// +// Verify that the object is a string; None is NOT legal. +// +inline bool checkString(PyObject* p) +{ +#if PY_VERSION_HEX >= 0x03000000 + return PyUnicode_Check(p) ? true : false; +#else + return PyString_Check(p) ? true : false; +#endif +} + +// +// Validate and retrieve a string argument; None is also legal. +// +bool getStringArg(PyObject*, const std::string&, std::string&); + +// +// Get the name of the current Python function. +// +std::string getFunction(); + +// +// Invokes Py_DECREF on a Python object. +// +class PyObjectHandle +{ +public: + + PyObjectHandle(PyObject* = 0); + PyObjectHandle(const PyObjectHandle&); + ~PyObjectHandle(); + + void operator=(PyObject*); + void operator=(const PyObjectHandle&); + + PyObject* get() const; + PyObject* release(); + +private: + + PyObject* _p; +}; + +// +// Manages the interpreter's exception. +// +class PyException +{ +public: + + // + // Retrieves the interpreter's current exception. + // + PyException(); + + // + // Uses the given exception. + // + PyException(PyObject*); + + // + // Convert the Python exception to its C++ equivalent. + // + void raise(); + + // + // If the Python exception is SystemExit, act on it. May not return. + // + void checkSystemExit(); + + PyObjectHandle ex; + +private: + + void raiseLocalException(); + std::string getTraceback(); + std::string getTypeName(); + + PyObjectHandle _type; + PyObjectHandle _tb; +}; + +// +// Convert Ice::StringSeq to and from a Python list. +// +bool listToStringSeq(PyObject*, Ice::StringSeq&); +bool stringSeqToList(const Ice::StringSeq&, PyObject*); + +// +// Convert a tuple to Ice::StringSeq. +// +bool tupleToStringSeq(PyObject*, Ice::StringSeq&); + +// +// Convert Ice::Context to and from a Python dictionary. +// +bool dictionaryToContext(PyObject*, Ice::Context&); +bool contextToDictionary(const Ice::Context&, PyObject*); + +// +// Returns a borrowed reference to the Python type object corresponding +// to the given Python type name. +// +PyObject* lookupType(const std::string&); + +// +// Creates an exception instance of the given type. +// +PyObject* createExceptionInstance(PyObject*); + +// +// Converts an Ice exception into a Python exception. +// +PyObject* convertException(const Ice::Exception&); + +// +// Converts an Ice exception into a Python exception and sets it in the Python environment. +// +void setPythonException(const Ice::Exception&); + +// +// Sets an exception in the Python environment. +// +void setPythonException(PyObject*); + +// +// Converts the interpreter's current exception into an Ice exception +// and throws it. +// +void throwPythonException(); + +// +// Handle the SystemExit exception. +// +void handleSystemExit(PyObject*); + +// +// Create a Python instance of Ice.Identity. +// +PyObject* createIdentity(const Ice::Identity&); + +// +// Verify that the object is Ice.Identity. +// +bool checkIdentity(PyObject*); + +// +// Assign values to members of an instance of Ice.Identity. +// +bool setIdentity(PyObject*, const Ice::Identity&); + +// +// Extract the members of Ice.Identity. +// +bool getIdentity(PyObject*, Ice::Identity&); + +// +// Create a Python instance of Ice.ProtocolVersion. +// +PyObject* createProtocolVersion(const Ice::ProtocolVersion&); + +// +// Create a Python instance of Ice.EncodingVersion. +// +PyObject* createEncodingVersion(const Ice::EncodingVersion&); + +// +// Extracts the members of an encoding version. +// +bool getEncodingVersion(PyObject*, Ice::EncodingVersion&); + +} + +extern "C" PyObject* IcePy_stringVersion(PyObject*); +extern "C" PyObject* IcePy_intVersion(PyObject*); +extern "C" PyObject* IcePy_currentProtocol(PyObject*); +extern "C" PyObject* IcePy_currentProtocolEncoding(PyObject*); +extern "C" PyObject* IcePy_currentEncoding(PyObject*); +extern "C" PyObject* IcePy_protocolVersionToString(PyObject*, PyObject*); +extern "C" PyObject* IcePy_stringToProtocolVersion(PyObject*, PyObject*); +extern "C" PyObject* IcePy_encodingVersionToString(PyObject*, PyObject*); +extern "C" PyObject* IcePy_stringToEncodingVersion(PyObject*, PyObject*); +extern "C" PyObject* IcePy_generateUUID(PyObject*); + +#endif diff --git a/python/modules/Makefile b/python/modules/Makefile new file mode 100644 index 00000000000..fe6cf9be39b --- /dev/null +++ b/python/modules/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = IcePy + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/python/modules/Makefile.mak b/python/modules/Makefile.mak new file mode 100644 index 00000000000..79fb8805721 --- /dev/null +++ b/python/modules/Makefile.mak @@ -0,0 +1,19 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +!include $(top_srcdir)\config\Make.rules.mak + +SUBDIRS = IcePy + +$(EVERYTHING):: + @for %i in ( $(SUBDIRS) ) do \ + @echo "making $@ in %i" && \ + cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1 diff --git a/python/python/.depend.mak b/python/python/.depend.mak new file mode 100644 index 00000000000..e46e1645583 --- /dev/null +++ b/python/python/.depend.mak @@ -0,0 +1,331 @@ + +Ice_BuiltinSequences_ice.py: \ + "$(slicedir)\Ice\BuiltinSequences.ice" + +Ice_Communicator_ice.py: \ + "$(slicedir)\Ice\Communicator.ice" \ + "$(slicedir)/Ice/LoggerF.ice" \ + "$(slicedir)/Ice/InstrumentationF.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/ObjectFactoryF.ice" \ + "$(slicedir)/Ice/RouterF.ice" \ + "$(slicedir)/Ice/LocatorF.ice" \ + "$(slicedir)/Ice/PluginF.ice" \ + "$(slicedir)/Ice/ImplicitContextF.ice" \ + "$(slicedir)/Ice/Current.ice" \ + "$(slicedir)/Ice/ConnectionF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/FacetMap.ice" + +Ice_CommunicatorF_ice.py: \ + "$(slicedir)\Ice\CommunicatorF.ice" + +Ice_Connection_ice.py: \ + "$(slicedir)\Ice\Connection.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Endpoint.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/EndpointF.ice" + +Ice_ConnectionF_ice.py: \ + "$(slicedir)\Ice\ConnectionF.ice" + +Ice_Current_ice.py: \ + "$(slicedir)\Ice\Current.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/ConnectionF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" + +Ice_Endpoint_ice.py: \ + "$(slicedir)\Ice\Endpoint.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/EndpointF.ice" + +Ice_EndpointF_ice.py: \ + "$(slicedir)\Ice\EndpointF.ice" + +Ice_EndpointTypes_ice.py: \ + "$(slicedir)\Ice\EndpointTypes.ice" + +Ice_FacetMap_ice.py: \ + "$(slicedir)\Ice\FacetMap.ice" + +Ice_Identity_ice.py: \ + "$(slicedir)\Ice\Identity.ice" + +Ice_ImplicitContext_ice.py: \ + "$(slicedir)\Ice\ImplicitContext.ice" \ + "$(slicedir)/Ice/LocalException.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Current.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/ConnectionF.ice" + +Ice_ImplicitContextF_ice.py: \ + "$(slicedir)\Ice\ImplicitContextF.ice" + +Ice_Instrumentation_ice.py: \ + "$(slicedir)\Ice\Instrumentation.ice" \ + "$(slicedir)/Ice/EndpointF.ice" \ + "$(slicedir)/Ice/ConnectionF.ice" \ + "$(slicedir)/Ice/Current.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" + +Ice_InstrumentationF_ice.py: \ + "$(slicedir)\Ice\InstrumentationF.ice" + +Ice_LocalException_ice.py: \ + "$(slicedir)\Ice\LocalException.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_Locator_ice.py: \ + "$(slicedir)\Ice\Locator.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/ProcessF.ice" + +Ice_LocatorF_ice.py: \ + "$(slicedir)\Ice\LocatorF.ice" + +Ice_Logger_ice.py: \ + "$(slicedir)\Ice\Logger.ice" + +Ice_LoggerF_ice.py: \ + "$(slicedir)\Ice\LoggerF.ice" + +Ice_Metrics_ice.py: \ + "$(slicedir)\Ice\Metrics.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_ObjectAdapter_ice.py: \ + "$(slicedir)\Ice\ObjectAdapter.ice" \ + "$(slicedir)/Ice/CommunicatorF.ice" \ + "$(slicedir)/Ice/ServantLocatorF.ice" \ + "$(slicedir)/Ice/LocatorF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/FacetMap.ice" \ + "$(slicedir)/Ice/Endpoint.ice" \ + "$(slicedir)/Ice/Version.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/EndpointF.ice" + +Ice_ObjectAdapterF_ice.py: \ + "$(slicedir)\Ice\ObjectAdapterF.ice" + +Ice_ObjectFactory_ice.py: \ + "$(slicedir)\Ice\ObjectFactory.ice" + +Ice_ObjectFactoryF_ice.py: \ + "$(slicedir)\Ice\ObjectFactoryF.ice" + +Ice_Plugin_ice.py: \ + "$(slicedir)\Ice\Plugin.ice" \ + "$(slicedir)/Ice/LoggerF.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_PluginF_ice.py: \ + "$(slicedir)\Ice\PluginF.ice" + +Ice_Process_ice.py: \ + "$(slicedir)\Ice\Process.ice" + +Ice_ProcessF_ice.py: \ + "$(slicedir)\Ice\ProcessF.ice" + +Ice_Properties_ice.py: \ + "$(slicedir)\Ice\Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_PropertiesAdmin_ice.py: \ + "$(slicedir)\Ice\PropertiesAdmin.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_PropertiesF_ice.py: \ + "$(slicedir)\Ice\PropertiesF.ice" + +Ice_Router_ice.py: \ + "$(slicedir)\Ice\Router.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_RouterF_ice.py: \ + "$(slicedir)\Ice\RouterF.ice" + +Ice_ServantLocator_ice.py: \ + "$(slicedir)\Ice\ServantLocator.ice" \ + "$(slicedir)/Ice/ObjectAdapterF.ice" \ + "$(slicedir)/Ice/Current.ice" \ + "$(slicedir)/Ice/ConnectionF.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/Version.ice" + +Ice_ServantLocatorF_ice.py: \ + "$(slicedir)\Ice\ServantLocatorF.ice" + +Ice_SliceChecksumDict_ice.py: \ + "$(slicedir)\Ice\SliceChecksumDict.ice" + +Ice_Version_ice.py: \ + "$(slicedir)\Ice\Version.ice" + +Glacier2_Metrics_ice.py: \ + "$(slicedir)\Glacier2\Metrics.ice" \ + "$(slicedir)/Ice/Metrics.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Glacier2_PermissionsVerifier_ice.py: \ + "$(slicedir)\Glacier2\PermissionsVerifier.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +Glacier2_PermissionsVerifierF_ice.py: \ + "$(slicedir)\Glacier2\PermissionsVerifierF.ice" + +Glacier2_Router_ice.py: \ + "$(slicedir)\Glacier2\Router.ice" \ + "$(slicedir)/Ice/Router.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/Glacier2/PermissionsVerifier.ice" + +Glacier2_RouterF_ice.py: \ + "$(slicedir)\Glacier2\RouterF.ice" + +Glacier2_Session_ice.py: \ + "$(slicedir)\Glacier2\Session.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" + +Glacier2_SSLInfo_ice.py: \ + "$(slicedir)\Glacier2\SSLInfo.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IceBox_IceBox_ice.py: \ + "$(slicedir)\IceBox\IceBox.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/CommunicatorF.ice" \ + "$(slicedir)/Ice/PropertiesF.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" + +IceGrid_Admin_ice.py: \ + "$(slicedir)\IceGrid\Admin.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/IceGrid/Exception.ice" \ + "$(slicedir)/IceGrid/Descriptor.ice" + +IceGrid_Descriptor_ice.py: \ + "$(slicedir)\IceGrid\Descriptor.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IceGrid_Exception_ice.py: \ + "$(slicedir)\IceGrid\Exception.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IceGrid_FileParser_ice.py: \ + "$(slicedir)\IceGrid\FileParser.ice" \ + "$(slicedir)/IceGrid/Admin.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/IceGrid/Exception.ice" \ + "$(slicedir)/IceGrid/Descriptor.ice" + +IceGrid_Locator_ice.py: \ + "$(slicedir)\IceGrid\Locator.ice" \ + "$(slicedir)/Ice/Locator.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/ProcessF.ice" + +IceGrid_Observer_ice.py: \ + "$(slicedir)\IceGrid\Observer.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/IceGrid/Exception.ice" \ + "$(slicedir)/IceGrid/Descriptor.ice" \ + "$(slicedir)/IceGrid/Admin.ice" \ + "$(slicedir)/Ice/Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" + +IceGrid_Query_ice.py: \ + "$(slicedir)\IceGrid\Query.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/IceGrid/Exception.ice" + +IceGrid_Registry_ice.py: \ + "$(slicedir)\IceGrid\Registry.ice" \ + "$(slicedir)/IceGrid/Exception.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/IceGrid/Session.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/IceGrid/Admin.ice" \ + "$(slicedir)/Ice/Properties.ice" \ + "$(slicedir)/Ice/PropertiesAdmin.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" \ + "$(slicedir)/IceGrid/Descriptor.ice" + +IceGrid_Session_ice.py: \ + "$(slicedir)\IceGrid\Session.ice" \ + "$(slicedir)/Glacier2/Session.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Glacier2/SSLInfo.ice" \ + "$(slicedir)/IceGrid/Exception.ice" + +IceGrid_UserAccountMapper_ice.py: \ + "$(slicedir)\IceGrid\UserAccountMapper.ice" + +IcePatch2_FileInfo_ice.py: \ + "$(slicedir)\IcePatch2\FileInfo.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IcePatch2_FileServer_ice.py: \ + "$(slicedir)\IcePatch2\FileServer.ice" \ + "$(slicedir)/IcePatch2/FileInfo.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IceStorm_Metrics_ice.py: \ + "$(slicedir)\IceStorm\Metrics.ice" \ + "$(slicedir)/Ice/Metrics.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" + +IceStorm_IceStorm_ice.py: \ + "$(slicedir)\IceStorm\IceStorm.ice" \ + "$(slicedir)/Ice/Identity.ice" \ + "$(slicedir)/Ice/SliceChecksumDict.ice" \ + "$(slicedir)/IceStorm/Metrics.ice" \ + "$(slicedir)/Ice/Metrics.ice" \ + "$(slicedir)/Ice/BuiltinSequences.ice" diff --git a/python/python/.gitignore b/python/python/.gitignore new file mode 100644 index 00000000000..3e3f00b9453 --- /dev/null +++ b/python/python/.gitignore @@ -0,0 +1,8 @@ +Glacier2/* +IceBox/* +IceGrid/* +IceMX/* +IcePatch2/* +IceStorm/* +*_ice.py +IcePy.* diff --git a/python/python/64/.gitignore b/python/python/64/.gitignore new file mode 100644 index 00000000000..39af5887579 --- /dev/null +++ b/python/python/64/.gitignore @@ -0,0 +1 @@ +# Dummy file, so that git retains this otherwise empty directory. diff --git a/python/python/Glacier2.py b/python/python/Glacier2.py new file mode 100644 index 00000000000..149dde48386 --- /dev/null +++ b/python/python/Glacier2.py @@ -0,0 +1,238 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +""" +Glacier2 module +""" + +import threading, traceback, copy + +# +# Import the Python extension. +# +import Ice +Ice.updateModule("Glacier2") + +import Glacier2_Router_ice +import Glacier2_Session_ice +import Glacier2_PermissionsVerifier_ice +import Glacier2_SSLInfo_ice +import Glacier2_Metrics_ice + +class SessionNotExistException(Exception): + def __init__(self): + pass + +class RestartSessionException(Exception): + def __init__(self): + pass + +class ConnectionCallbackI(Ice.ConnectionCallback): + def __init__(self, app): + self._app = app + + def heartbeat(self, conn): + pass + + def closed(self, conn): + self._app.sessionDestroyed() + + +class Application(Ice.Application): + + def __init__(self, signalPolicy=0): # HandleSignals=0 + '''The constructor accepts an optional argument indicating +whether to handle signals. The value should be either +Application.HandleSignals (the default) or +Application.NoSignalHandling. +''' + + if type(self) == Application: + raise RuntimeError("Glacier2.Application is an abstract class") + + Ice.Application.__init__(self, signalPolicy) + + Application._adapter = None + Application._router = None + Application._session = None + Application._createdSession = False + Application._category = None + + def run(self, args): + raise RuntimeError('run should not be called on Glacier2.Application - call runWithSession instead') + + def runWithSession(self, args): + raise RuntimeError('runWithSession() not implemented') + + def createSession(self, args): + raise RuntimeError('createSession() not implemented') + + def restart(self): + raise RestartSessionException() + + def sessionDestroyed(self): + pass + + def router(self): + return Application._router + router = classmethod(router) + + def session(self): + return Application._session + session = classmethod(session) + + def categoryForClient(self): + if Application._router == None: + raise SessionNotExistException() + return Application._category + + def createCallbackIdentity(self, name): + return Ice.Identity(name, self.categoryForClient()) + + def addWithUUID(self, servant): + return self.objectAdapter().add(servant, self.createCallbackIdentity(Ice.generateUUID())) + + def objectAdapter(self): + if Application._router == None: + raise SessionNotExistException() + if Application._adapter == None: + Application._adapter = self.communicator().createObjectAdapterWithRouter("", Application._router) + Application._adapter.activate() + return Application._adapter + + def doMainInternal(self, args, initData): + # Reset internal state variables from Ice.Application. The + # remainder are reset at the end of this method. + Ice.Application._callbackInProgress = False + Ice.Application._destroyed = False + Ice.Application._interrupted = False + + restart = False + status = 0 + + try: + Ice.Application._communicator = Ice.initialize(args, initData) + + Application._router = RouterPrx.uncheckedCast(Ice.Application.communicator().getDefaultRouter()) + if Application._router == None: + Ice.getProcessLogger().error("no glacier2 router configured") + status = 1 + else: + # + # The default is to destroy when a signal is received. + # + if Ice.Application._signalPolicy == Ice.Application.HandleSignals: + Ice.Application.destroyOnInterrupt() + + # If createSession throws, we're done. + try: + Application._session = self.createSession() + Application._createdSession = True + except Ice.LocalException: + Ice.getProcessLogger().error(traceback.format_exc()) + status = 1 + + if Application._createdSession: + acmTimeout = 0 + try: + acmTimeout = Application._router.getACMTimeout() + except(Ice.OperationNotExistException): + pass + if acmTimeout <= 0: + acmTimeout = Application._router.getSessionTimeout() + if acmTimeout > 0: + connection = Application._router.ice_getCachedConnection() + assert(connection) + connection.setACM(acmTimeout, Ice.Unset, Ice.ACMHeartbeat.HeartbeatAlways) + connection.setCallback(ConnectionCallbackI(self)) + Application._category = Application._router.getCategoryForClient() + status = self.runWithSession(args) + + # We want to restart on those exceptions which indicate a + # break down in communications, but not those exceptions that + # indicate a programming logic error (ie: marshal, protocol + # failure, etc). + except(RestartSessionException): + restart = True + except(Ice.ConnectionRefusedException, Ice.ConnectionLostException, Ice.UnknownLocalException, \ + Ice.RequestFailedException, Ice.TimeoutException): + Ice.getProcessLogger().error(traceback.format_exc()) + restart = True + except: + Ice.getProcessLogger().error(traceback.format_exc()) + status = 1 + + # + # Don't want any new interrupt and at this point (post-run), + # it would not make sense to release a held signal to run + # shutdown or destroy. + # + if Ice.Application._signalPolicy == Ice.Application.HandleSignals: + Ice.Application.ignoreInterrupt() + + Ice.Application._condVar.acquire() + while Ice.Application._callbackInProgress: + Ice.Application._condVar.wait() + if Ice.Application._destroyed: + Ice.Application._communicator = None + else: + Ice.Application._destroyed = True + # + # And _communicator != None, meaning will be destroyed + # next, _destroyed = True also ensures that any + # remaining callback won't do anything + # + Ice.Application._condVar.release() + + if Application._createdSession and Application._router: + try: + Application._router.destroySession() + except (Ice.ConnectionLostException, SessionNotExistException): + pass + except: + Ice.getProcessLogger().error("unexpected exception when destroying the session " + \ + traceback.format_exc()) + Application._router = None + + if Ice.Application._communicator: + try: + Ice.Application._communicator.destroy() + except: + getProcessLogger().error(traceback.format_exc()) + status = 1 + + Ice.Application._communicator = None + + # Reset internal state. We cannot reset the Application state + # here, since _destroyed must remain true until we re-run + # this method. + Application._adapter = None + Application._router = None + Application._session = None + Application._createdSession = False + Application._category = None + + return (restart, status) + + def doMain(self, args, initData): + # Set the default properties for all Glacier2 applications. + initData.properties.setProperty("Ice.RetryIntervals", "-1") + + restart = True + ret = 0 + while restart: + # A copy of the initialization data and the string seq + # needs to be passed to doMainInternal, as these can be + # changed by the application. + id = copy.copy(initData) + if id.properties: + id.properties = id.properties.clone() + argsCopy = args[:] + (restart, ret) = self.doMainInternal(argsCopy, initData) + return ret diff --git a/python/python/Ice.py b/python/python/Ice.py new file mode 100644 index 00000000000..b8c9f0a8721 --- /dev/null +++ b/python/python/Ice.py @@ -0,0 +1,1588 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +""" +Ice module +""" + +import sys, string, imp, os, threading, warnings, datetime + +# +# RTTI problems can occur in C++ code unless we modify Python's dlopen flags. +# Note that changing these flags might cause problems for other extensions +# loaded by the application (see bug 3660), so we restore the original settings +# after loading IcePy. +# +_dlopenflags = -1 +try: + _dlopenflags = sys.getdlopenflags() + + try: + import dl + sys.setdlopenflags(dl.RTLD_NOW|dl.RTLD_GLOBAL) + except ImportError: + # + # If the dl module is not available and we're running on a Linux + # platform, use the hard coded value of RTLD_NOW|RTLD_GLOBAL. + # + if sys.platform.startswith("linux"): + sys.setdlopenflags(258) + pass + +except AttributeError: + # + # sys.getdlopenflags() is not supported (we're probably running on Windows). + # + pass + +# +# Import the Python extension. +# +import IcePy + +# +# Restore the dlopen flags. +# +if _dlopenflags >= 0: + sys.setdlopenflags(_dlopenflags) + +# +# Give the extension an opportunity to clean up before a graceful exit. +# +import atexit +atexit.register(IcePy.cleanup) + +# +# Add some symbols to the Ice module. +# +ObjectPrx = IcePy.ObjectPrx +stringVersion = IcePy.stringVersion +intVersion = IcePy.intVersion +currentProtocol = IcePy.currentProtocol +currentProtocolEncoding = IcePy.currentProtocolEncoding +currentEncoding = IcePy.currentEncoding +stringToProtocolVersion = IcePy.stringToProtocolVersion +protocolVersionToString = IcePy.protocolVersionToString +stringToEncodingVersion = IcePy.stringToEncodingVersion +encodingVersionToString = IcePy.encodingVersionToString +generateUUID = IcePy.generateUUID +loadSlice = IcePy.loadSlice +AsyncResult = IcePy.AsyncResult +Unset = IcePy.Unset + +# +# This value is used as the default value for struct types in the constructors +# of user-defined types. It allows us to determine whether the application has +# supplied a value. (See bug 3676) +# +_struct_marker = object() + +# +# Core Ice types. +# +class Object(object): + def ice_isA(self, id, current=None): + '''Determines whether the target object supports the interface denoted +by the given Slice type id. +Arguments: + id The Slice type id +Returns: + True if the target object supports the interface, or false otherwise. +''' + return id in self.ice_ids(current) + + def ice_ping(self, current=None): + '''A reachability test for the target object.''' + pass + + def ice_ids(self, current=None): + '''Obtains the type ids corresponding to the Slice interface +that are supported by the target object. +Returns: + A list of type ids. +''' + return [ self.ice_id(current) ] + + def ice_id(self, current=None): + '''Obtains the type id corresponding to the most-derived Slice +interface supported by the target object. +Returns: + The type id. +''' + return '::Ice::Object' + + def ice_staticId(): + '''Obtains the type id of this Slice class or interface. +Returns: + The type id. +''' + return '::Ice::Object' + ice_staticId = staticmethod(ice_staticId) + + # + # Do not define these here. They will be invoked if defined by a subclass. + # + #def ice_preMarshal(self): + # pass + # + #def ice_postUnmarshal(self): + # pass + +# +# LocalObject is deprecated; use the Python base 'object' type instead. +# +class LocalObject(object): + pass + +class Blobject(Object): + '''Special-purpose servant base class that allows a subclass to +handle synchronous Ice invocations as "blobs" of bytes.''' + + def ice_invoke(self, bytes, current): + '''Dispatch a synchronous Ice invocation. The operation's +arguments are encoded in the bytes argument. The return +value must be a tuple of two values: the first is a +boolean indicating whether the operation succeeded (True) +or raised a user exception (False), and the second is +the encoded form of the operation's results or the user +exception. +''' + pass + +class BlobjectAsync(Object): + '''Special-purpose servant base class that allows a subclass to +handle asynchronous Ice invocations as "blobs" of bytes.''' + + def ice_invoke_async(self, cb, bytes, current): + '''Dispatch an asynchronous Ice invocation. The operation's +arguments are encoded in the bytes argument. When the +dispatch is complete, the subclass can invoke either +ice_response or ice_exception on the supplied callback +object. +''' + pass + +# +# Exceptions. +# +class Exception(Exception): # Derives from built-in base 'Exception' class. + '''The base class for all Ice exceptions.''' + def __str__(self): + return self.__class__.__name__ + + def ice_name(self): + '''Returns the type name of this exception.''' + return self._ice_name + +class LocalException(Exception): + '''The base class for all Ice run-time exceptions.''' + def __init__(self, args=''): + self.args = args + +class UserException(Exception): + '''The base class for all user-defined exceptions.''' + pass + +class EnumBase(object): + def __init__(self, _n, _v): + self._name = _n + self._value = _v + + def __str__(self): + return self._name + + __repr__ = __str__ + + def __hash__(self): + return self._value + + def __lt__(self, other): + if isinstance(other, self.__class__): + return self._value < other._value; + elif other == None: + return False + return NotImplemented + + def __le__(self, other): + if isinstance(other, self.__class__): + return self._value <= other._value; + elif other == None: + return False + return NotImplemented + + def __eq__(self, other): + if isinstance(other, self.__class__): + return self._value == other._value; + elif other == None: + return False + return NotImplemented + + def __ne__(self, other): + if isinstance(other, self.__class__): + return self._value != other._value; + elif other == None: + return False + return NotImplemented + + def __gt__(self, other): + if isinstance(other, self.__class__): + return self._value > other._value; + elif other == None: + return False + return NotImplemented + + def __ge__(self, other): + if isinstance(other, self.__class__): + return self._value >= other._value; + elif other == None: + return False + return NotImplemented + + def _getName(self): + return self._name + + def _getValue(self): + return self._value + + name = property(_getName) + value = property(_getValue) + +class SlicedData(object): + # + # Members: + # + # slices - tuple of SliceInfo + # + pass + +class SliceInfo(object): + # + # Members: + # + # typeId - string + # compactId - int + # bytes - string + # objects - tuple of Ice.Object + pass + +# +# Native PropertiesAdmin admin facet. +# +NativePropertiesAdmin = IcePy.NativePropertiesAdmin + +class PropertiesAdminUpdateCallback(object): + '''Callback class to get notifications of property updates passed + through the Properties admin facet''' + + def updated(self, props): + pass + +class UnknownSlicedObject(Object): + # + # Members: + # + # unknownTypeId - string + pass + +def getSliceDir(): + '''Convenience function for locating the directory containing the Slice files.''' + + # + # Detect setup.py installation in site-packages. The slice + # files live along side Ice.py + # + dir = os.path.join(os.path.dirname(__file__), "slice") + if os.path.isdir(dir): + return dir + + # + # Get the parent of the directory containing this file (Ice.py). + # + pyHome = os.path.join(os.path.dirname(__file__), "..") + + # + # For an installation from a source distribution, a binary tarball, or a + # Windows installer, the "slice" directory is a sibling of the "python" + # directory. + # + dir = os.path.join(pyHome, "slice") + if os.path.exists(dir): + return os.path.normpath(dir) + + # + # In a source distribution, the "slice" directory is one level higher. + # + dir = os.path.join(pyHome, "..", "slice") + if os.path.exists(dir): + return os.path.normpath(dir) + + iceVer = stringVersion() + + if sys.platform[:5] == "linux": + # + # Check the default RPM location. + # + dir = os.path.join("/", "usr", "share", "Ice-" + iceVer, "slice") + if os.path.exists(dir): + return dir + + elif sys.platform == "darwin": + # + # Check the default OS X location. + # + dir = os.path.join("/", "Library", "Developer", "Ice-" + iceVer, "slice") + if os.path.exists(dir): + return dir + + return None + +# +# Utilities for use by generated code. +# + +_pendingModules = {} + +def openModule(name): + global _pendingModules + if name in sys.modules: + result = sys.modules[name] + elif name in _pendingModules: + result = _pendingModules[name] + else: + result = createModule(name) + + return result + +def createModule(name): + global _pendingModules + l = name.split(".") + curr = '' + mod = None + + for s in l: + curr = curr + s + + if curr in sys.modules: + mod = sys.modules[curr] + elif curr in _pendingModules: + mod = _pendingModules[curr] + else: + nmod = imp.new_module(curr) + _pendingModules[curr] = nmod + mod = nmod + + curr = curr + "." + + return mod + +def updateModule(name): + global _pendingModules + if name in _pendingModules: + pendingModule = _pendingModules[name] + mod = sys.modules[name] + mod.__dict__.update(pendingModule.__dict__) + del _pendingModules[name] + +def updateModules(): + global _pendingModules + for name in _pendingModules.keys(): + if name in sys.modules: + sys.modules[name].__dict__.update(_pendingModules[name].__dict__) + else: + sys.modules[name] = _pendingModules[name] + _pendingModules = {} + +def createTempClass(): + class __temp: pass + return __temp + +class FormatType(object): + def __init__(self, val): + assert(val >= 0 and val < 3) + self.value = val + +FormatType.DefaultFormat = FormatType(0) +FormatType.CompactFormat = FormatType(1) +FormatType.SlicedFormat = FormatType(2) + +# +# Forward declarations. +# +IcePy._t_Object = IcePy.declareClass('::Ice::Object') +IcePy._t_ObjectPrx = IcePy.declareProxy('::Ice::Object') +IcePy._t_LocalObject = IcePy.declareClass('::Ice::LocalObject') + +# +# Sequence mappings. +# +IcePy.SEQ_DEFAULT = 0 +IcePy.SEQ_TUPLE = 1 +IcePy.SEQ_LIST = 2 +#IcePy.SEQ_ARRAY = 3 + +# +# Slice checksum dictionary. +# +sliceChecksums = {} + +# +# Import generated Ice modules. +# +import Ice_BuiltinSequences_ice +import Ice_Communicator_ice +import Ice_Current_ice +import Ice_ImplicitContext_ice +import Ice_Endpoint_ice +import Ice_EndpointTypes_ice +import Ice_Identity_ice +import Ice_LocalException_ice +import Ice_Locator_ice +import Ice_Logger_ice +import Ice_ObjectAdapter_ice +import Ice_ObjectFactory_ice +import Ice_Process_ice +import Ice_Properties_ice +import Ice_Router_ice +import Ice_ServantLocator_ice +import Ice_Connection_ice +import Ice_Version_ice +import Ice_Instrumentation_ice +import Ice_Metrics_ice + +# +# Replace EndpointInfo with our implementation. +# +del EndpointInfo +EndpointInfo = IcePy.EndpointInfo +del IPEndpointInfo +IPEndpointInfo = IcePy.IPEndpointInfo +del TCPEndpointInfo +TCPEndpointInfo = IcePy.TCPEndpointInfo +del UDPEndpointInfo +UDPEndpointInfo = IcePy.UDPEndpointInfo +del WSEndpointInfo +WSEndpointInfo = IcePy.WSEndpointInfo +del OpaqueEndpointInfo +OpaqueEndpointInfo = IcePy.OpaqueEndpointInfo + +# +# Replace ConnectionInfo with our implementation. +# +del ConnectionInfo +ConnectionInfo = IcePy.ConnectionInfo +del IPConnectionInfo +IPConnectionInfo = IcePy.IPConnectionInfo +del TCPConnectionInfo +TCPConnectionInfo = IcePy.TCPConnectionInfo +del UDPConnectionInfo +UDPConnectionInfo = IcePy.UDPConnectionInfo +del WSConnectionInfo +WSConnectionInfo = IcePy.WSConnectionInfo + +class ThreadNotification(object): + '''Base class for thread notification callbacks. A subclass must +define the start and stop methods.''' + + def __init__(self): + pass + + def start(): + '''Invoked in the context of a thread created by the Ice run time.''' + pass + + def stop(): + '''Invoked in the context of an Ice run-time thread that is about +to terminate.''' + pass + +class BatchRequest(object): + '''Base class for batch request interceptor. A subclass must +define the enqueue method.''' + def __init__(self, size, operation, proxy): + self._size = size + self._operation = operation + self._proxy = proxy + + def getSize(): + return self._size + + def getOperation(): + return self._operation + + def getProxy(): + return self._proxy + + def enqueue(): + '''Call enqueue from the batch request interceptor enqueue +implementation to confirm the batching a this request.''' + pass + +class BatchRequestInterceptor(object): + '''Base class for batch request interceptor. A subclass must +define the enqueue method.''' + + def __init__(self): + pass + + def enqueue(request, queueCount, queueSize): + '''Invoked when a request is batched.''' + pass + +# +# Initialization data. +# +class InitializationData(object): + '''The attributes of this class are used to initialize a new +communicator instance. The supported attributes are as follows: + +properties: An instance of Ice.Properties. You can use the + Ice.createProperties function to create a new property set. + +logger: An instance of Ice.Logger. + +threadHook: An object that implements ThreadNotification. +''' + def __init__(self): + self.properties = None + self.logger = None + self.threadHook = None + self.batchRequestInterceptor = None + +# +# Communicator wrapper. +# +class CommunicatorI(Communicator): + def __init__(self, impl): + self._impl = impl + impl._setWrapper(self) + + def destroy(self): + self._impl.destroy() + + def shutdown(self): + self._impl.shutdown() + + def waitForShutdown(self): + # + # If invoked by the main thread, waitForShutdown only blocks for + # the specified timeout in order to give us a chance to handle + # signals. + # + while not self._impl.waitForShutdown(500): + pass + + def isShutdown(self): + return self._impl.isShutdown() + + def stringToProxy(self, str): + return self._impl.stringToProxy(str) + + def proxyToString(self, obj): + return self._impl.proxyToString(obj) + + def propertyToProxy(self, str): + return self._impl.propertyToProxy(str) + + def proxyToProperty(self, obj, str): + return self._impl.proxyToProperty(obj, str) + + def stringToIdentity(self, str): + return self._impl.stringToIdentity(str) + + def identityToString(self, ident): + return self._impl.identityToString(ident) + + def createObjectAdapter(self, name): + adapter = self._impl.createObjectAdapter(name) + return ObjectAdapterI(adapter) + + def createObjectAdapterWithEndpoints(self, name, endpoints): + adapter = self._impl.createObjectAdapterWithEndpoints(name, endpoints) + return ObjectAdapterI(adapter) + + def createObjectAdapterWithRouter(self, name, router): + adapter = self._impl.createObjectAdapterWithRouter(name, router) + return ObjectAdapterI(adapter) + + def addObjectFactory(self, factory, id): + self._impl.addObjectFactory(factory, id) + + def findObjectFactory(self, id): + return self._impl.findObjectFactory(id) + + def getImplicitContext(self): + context = self._impl.getImplicitContext() + if context == None: + return None; + else: + return ImplicitContextI(context) + + def getProperties(self): + properties = self._impl.getProperties() + return PropertiesI(properties) + + def getLogger(self): + logger = self._impl.getLogger() + if isinstance(logger, Logger): + return logger + else: + return LoggerI(logger) + + def getStats(self): + raise RuntimeError("operation `getStats' not implemented") + + def getDefaultRouter(self): + return self._impl.getDefaultRouter() + + def setDefaultRouter(self, rtr): + self._impl.setDefaultRouter(rtr) + + def getDefaultLocator(self): + return self._impl.getDefaultLocator() + + def setDefaultLocator(self, loc): + self._impl.setDefaultLocator(loc) + + def getPluginManager(self): + raise RuntimeError("operation `getPluginManager' not implemented") + + def flushBatchRequests(self): + self._impl.flushBatchRequests() + + def begin_flushBatchRequests(self, _ex=None, _sent=None): + return self._impl.begin_flushBatchRequests(_ex, _sent) + + def end_flushBatchRequests(self, r): + return self._impl.end_flushBatchRequests(r) + + def createAdmin(self, adminAdapter, adminIdentity): + return self._impl.createAdmin(adminAdapter, adminIdentity) + + def getAdmin(self): + return self._impl.getAdmin() + + def addAdminFacet(self, servant, facet): + self._impl.addAdminFacet(servant, facet) + + def findAdminFacet(self, facet): + return self._impl.findAdminFacet(facet) + + def findAllAdminFacets(self): + return self._impl.findAllAdminFacets() + + def removeAdminFacet(self, facet): + return self._impl.removeAdminFacet(facet) + +# +# Ice.initialize() +# +def initialize(args=None, data=None): + '''Initializes a new communicator. The optional arguments represent +an argument list (such as sys.argv) and an instance of InitializationData. +You can invoke this function as follows: + +Ice.initialize() +Ice.initialize(args) +Ice.initialize(data) +Ice.initialize(args, data) + +If you supply an argument list, the function removes those arguments from +the list that were recognized by the Ice run time. +''' + communicator = IcePy.Communicator(args, data) + return CommunicatorI(communicator) + +# +# ObjectAdapter wrapper. +# +class ObjectAdapterI(ObjectAdapter): + def __init__(self, impl): + self._impl = impl + + def getName(self): + return self._impl.getName() + + def getCommunicator(self): + communicator = self._impl.getCommunicator() + return communicator._getWrapper() + + def activate(self): + self._impl.activate() + + def hold(self): + self._impl.hold() + + def waitForHold(self): + # + # If invoked by the main thread, waitForHold only blocks for + # the specified timeout in order to give us a chance to handle + # signals. + # + while not self._impl.waitForHold(1000): + pass + + def deactivate(self): + self._impl.deactivate() + + def waitForDeactivate(self): + # + # If invoked by the main thread, waitForDeactivate only blocks for + # the specified timeout in order to give us a chance to handle + # signals. + # + while not self._impl.waitForDeactivate(1000): + pass + + def isDeactivated(self): + self._impl.isDeactivated() + + def destroy(self): + self._impl.destroy() + + def add(self, servant, id): + return self._impl.add(servant, id) + + def addFacet(self, servant, id, facet): + return self._impl.addFacet(servant, id, facet) + + def addWithUUID(self, servant): + return self._impl.addWithUUID(servant) + + def addFacetWithUUID(self, servant, facet): + return self._impl.addFacetWIthUUID(servant, facet) + + def addDefaultServant(self, servant, category): + self._impl.addDefaultServant(servant, category) + + def remove(self, id): + return self._impl.remove(id) + + def removeFacet(self, id, facet): + return self._impl.removeFacet(id, facet) + + def removeAllFacets(self, id): + return self._impl.removeAllFacets(id) + + def removeDefaultServant(self, category): + return self._impl.removeDefaultServant(category) + + def find(self, id): + return self._impl.find(id) + + def findFacet(self, id, facet): + return self._impl.findFacet(id, facet) + + def findAllFacets(self, id): + return self._impl.findAllFacets(id) + + def findByProxy(self, proxy): + return self._impl.findByProxy(proxy) + + def findDefaultServant(self, category): + return self._impl.findDefaultServant(category) + + def addServantLocator(self, locator, category): + self._impl.addServantLocator(locator, category) + + def removeServantLocator(self, category): + return self._impl.removeServantLocator(category) + + def findServantLocator(self, category): + return self._impl.findServantLocator(category) + + def createProxy(self, id): + return self._impl.createProxy(id) + + def createDirectProxy(self, id): + return self._impl.createDirectProxy(id) + + def createIndirectProxy(self, id): + return self._impl.createIndirectProxy(id) + + def createReverseProxy(self, id): + return self._impl.createReverseProxy(id) + + def setLocator(self, loc): + self._impl.setLocator(loc) + + def getLocator(self): + return self._impl.getLocator() + + def refreshPublishedEndpoints(self): + self._impl.refreshPublishedEndpoints() + + def getEndpoints(self): + return self._impl.getEndpoints() + + def getPublishedEndpoints(self): + return self._impl.getPublishedEndpoints() + +# +# Logger wrapper. +# +class LoggerI(Logger): + def __init__(self, impl): + self._impl = impl + + def _print(self, message): + return self._impl._print(message) + + def trace(self, category, message): + return self._impl.trace(category, message) + + def warning(self, message): + return self._impl.warning(message) + + def error(self, message): + return self._impl.error(message) + + def getPrefix(self): + return self._impl.getPrefix() + + def cloneWithPrefix(self, prefix): + logger = self._impl.cloneWithPrefix(prefix) + return LoggerI(logger) + +# +# Properties wrapper. +# +class PropertiesI(Properties): + def __init__(self, impl): + self._impl = impl + + def getProperty(self, key): + return self._impl.getProperty(key) + + def getPropertyWithDefault(self, key, value): + return self._impl.getPropertyWithDefault(key, value) + + def getPropertyAsInt(self, key): + return self._impl.getPropertyAsInt(key) + + def getPropertyAsIntWithDefault(self, key, value): + return self._impl.getPropertyAsIntWithDefault(key, value) + + def getPropertyAsList(self, key): + return self._impl.getPropertyAsList(key) + + def getPropertyAsListWithDefault(self, key, value): + return self._impl.getPropertyAsListWithDefault(key, value) + + def getPropertiesForPrefix(self, prefix): + return self._impl.getPropertiesForPrefix(prefix) + + def setProperty(self, key, value): + self._impl.setProperty(key, value) + + def getCommandLineOptions(self): + return self._impl.getCommandLineOptions() + + def parseCommandLineOptions(self, prefix, options): + return self._impl.parseCommandLineOptions(prefix, options) + + def parseIceCommandLineOptions(self, options): + return self._impl.parseIceCommandLineOptions(options) + + def load(self, file): + self._impl.load(file) + + def clone(self): + properties = self._impl.clone() + return PropertiesI(properties) + + def __iter__(self): + dict = self._impl.getPropertiesForPrefix('') + return iter(dict) + + def __str__(self): + return str(self._impl) + +# +# Ice.createProperties() +# +def createProperties(args=None, defaults=None): + '''Creates a new property set. The optional arguments represent +an argument list (such as sys.argv) and a property set that supplies +default values. You can invoke this function as follows: + +Ice.createProperties() +Ice.createProperties(args) +Ice.createProperties(defaults) +Ice.createProperties(args, defaults) + +If you supply an argument list, the function removes those arguments +from the list that were recognized by the Ice run time. +''' + + properties = IcePy.createProperties(args, defaults) + return PropertiesI(properties) + +# +# Ice.getProcessLogger() +# Ice.setProcessLogger() +# +def getProcessLogger(): + '''Returns the default logger object.''' + logger = IcePy.getProcessLogger() + if isinstance(logger, Logger): + return logger + else: + return LoggerI(logger) + +def setProcessLogger(logger): + '''Sets the default logger object.''' + IcePy.setProcessLogger(logger) + +# +# ImplicitContext wrapper +# +class ImplicitContextI(ImplicitContext): + def __init__(self, impl): + self._impl = impl + + def setContext(self, ctx): + self._impl.setContext(ctx) + + def getContext(self): + return self._impl.getContext() + + def containsKey(self, key): + return self._impl.containsKey(key) + + def get(self, key): + return self._impl.get(key) + + def put(self, key, value): + return self._impl.put(key, value) + + def remove(self, key): + return self._impl.remove(key) + + +# +# Its not possible to block in a python signal handler since this +# blocks the main thread from doing further work. As such we queue the +# signal with a worker thread which then "dispatches" the signal to +# the registered callback object. +# +# Note the interface is the same as the C++ CtrlCHandler +# implementation, however, the implementation is different. +# +class CtrlCHandler(threading.Thread): + # Class variable referring to the one and only handler for use + # from the signal handling callback. + _self = None + + def __init__(self): + threading.Thread.__init__(self) + + if CtrlCHandler._self != None: + raise RuntimeError("Only a single instance of a CtrlCHandler can be instantiated.") + CtrlCHandler._self = self + + # State variables. These are not class static variables. + self._condVar = threading.Condition() + self._queue = [] + self._done = False + self._callback = None + + # + # Setup and install signal handlers + # + if 'SIGHUP' in signal.__dict__: + signal.signal(signal.SIGHUP, CtrlCHandler.signalHandler) + if 'SIGBREAK' in signal.__dict__: + signal.signal(signal.SIGBREAK, CtrlCHandler.signalHandler) + signal.signal(signal.SIGINT, CtrlCHandler.signalHandler) + signal.signal(signal.SIGTERM, CtrlCHandler.signalHandler) + + # Start the thread once everything else is done. + self.start() + + # Dequeue and dispatch signals. + def run(self): + while True: + self._condVar.acquire() + while len(self._queue) == 0 and not self._done: + self._condVar.wait() + if self._done: + self._condVar.release() + break + sig, callback = self._queue.pop() + self._condVar.release() + if callback: + callback(sig) + + # Destroy the object. Wait for the thread to terminate and cleanup + # the internal state. + def destroy(self): + self._condVar.acquire() + self._done = True + self._condVar.notify() + self._condVar.release() + + # Wait for the thread to terminate + self.join() + # + # Cleanup any state set by the CtrlCHandler. + # + if 'SIGHUP' in signal.__dict__: + signal.signal(signal.SIGHUP, signal.SIG_DFL) + if 'SIGBREAK' in signal.__dict__: + signal.signal(signal.SIGBREAK, signal.SIG_DFL) + signal.signal(signal.SIGINT, signal.SIG_DFL) + signal.signal(signal.SIGTERM, signal.SIG_DFL) + CtrlCHandler._self = None + + def setCallback(self, callback): + self._condVar.acquire() + self._callback = callback + self._condVar.release() + + def getCallback(self): + self._condVar.acquire() + callback = self._callback + self._condVar.release() + return callback + + # Private. Only called by the signal handling mechanism. + def signalHandler(self, sig, frame): + self._self._condVar.acquire() + # + # The signal AND the current callback are queued together. + # + self._self._queue.append([sig, self._self._callback]) + self._self._condVar.notify() + self._self._condVar.release() + signalHandler = classmethod(signalHandler) + +# +# Application logger. +# +class _ApplicationLoggerI(Logger): + def __init__(self, prefix): + if len(prefix) > 0: + self._prefix = prefix + ": " + else: + self._prefix = "" + self._outputMutex = threading.Lock() + + def _print(self, message): + s = "[ " + str(datetime.datetime.now()) + " " + self._prefix + self._outputMutex.acquire() + sys.stderr.write(message + "\n") + self._outputMutex.release() + + def trace(self, category, message): + s = "[ " + str(datetime.datetime.now()) + " " + self._prefix + if len(category) > 0: + s += category + ": " + s += message + " ]" + + s = s.replace("\n", "\n ") + + self._outputMutex.acquire() + sys.stderr.write(s + "\n") + self._outputMutex.release() + + def warning(self, message): + self._outputMutex.acquire() + sys.stderr.write(str(datetime.datetime.now()) + " " + self._prefix + "warning: " + message + "\n") + self._outputMutex.release() + + def error(self, message): + self._outputMutex.acquire() + sys.stderr.write(str(datetime.datetime.now()) + " " + self._prefix + "error: " + message + "\n") + self._outputMutex.release() + +# +# Application class. +# +import signal, traceback +class Application(object): + '''Convenience class that initializes a communicator and reacts +gracefully to signals. An application must define a subclass +of this class and supply an implementation of the run method. +''' + + def __init__(self, signalPolicy=0): # HandleSignals=0 + '''The constructor accepts an optional argument indicating +whether to handle signals. The value should be either +Application.HandleSignals (the default) or +Application.NoSignalHandling. +''' + if type(self) == Application: + raise RuntimeError("Ice.Application is an abstract class") + Application._signalPolicy = signalPolicy + + def main(self, args, configFile=None, initData=None): + '''The main entry point for the Application class. The arguments +are an argument list (such as sys.argv), the name of an Ice +configuration file (optional), and an instance of +InitializationData (optional). This method does not return +until after the completion of the run method. The return +value is an integer representing the exit status. +''' + + if Application._communicator: + getProcessLogger().error(args[0] + ": only one instance of the Application class can be used") + return 1 + + # + # We parse the properties here to extract Ice.ProgramName. + # + if not initData: + initData = InitializationData() + if configFile: + try: + initData.properties = createProperties(None, initData.properties) + initData.properties.load(configFile) + except: + getProcessLogger().error(traceback.format_exc()) + return 1 + initData.properties = createProperties(args, initData.properties) + + # + # If the process logger is the default logger, we replace it with a + # a logger which is using the program name for the prefix. + # + if isinstance(getProcessLogger(), LoggerI): + setProcessLogger(_ApplicationLoggerI(initData.properties.getProperty("Ice.ProgramName"))) + + # + # Install our handler for the signals we are interested in. We assume main() + # is called from the main thread. + # + Application._ctrlCHandler = CtrlCHandler() + + try: + Application._interrupted = False + Application._appName = initData.properties.getPropertyWithDefault("Ice.ProgramName", args[0]) + Application._application = self + + # + # Used by _destroyOnInterruptCallback and _shutdownOnInterruptCallback. + # + Application._nohup = initData.properties.getPropertyAsInt("Ice.Nohup") > 0 + + # + # The default is to destroy when a signal is received. + # + if Application._signalPolicy == Application.HandleSignals: + Application.destroyOnInterrupt() + + status = self.doMain(args, initData) + except: + getProcessLogger().error(traceback.format_exc()) + status = 1 + # + # Set _ctrlCHandler to 0 only once communicator.destroy() has + # completed. + # + Application._ctrlCHandler.destroy() + Application._ctrlCHandler = None + + return status + + def doMain(self, args, initData): + try: + Application._communicator = initialize(args, initData) + Application._destroyed = False + status = self.run(args) + + except: + getProcessLogger().error(traceback.format_exc()) + status = 1 + + # + # Don't want any new interrupt and at this point (post-run), + # it would not make sense to release a held signal to run + # shutdown or destroy. + # + if Application._signalPolicy == Application.HandleSignals: + Application.ignoreInterrupt() + + Application._condVar.acquire() + while Application._callbackInProgress: + Application._condVar.wait() + if Application._destroyed: + Application._communicator = None + else: + Application._destroyed = True + # + # And _communicator != 0, meaning will be destroyed + # next, _destroyed = true also ensures that any + # remaining callback won't do anything + # + Application._application = None + Application._condVar.release() + + if Application._communicator: + try: + Application._communicator.destroy() + except: + getProcessLogger().error(traceback.format_exc()) + status = 1 + Application._communicator = None + return status + + def run(self, args): + '''This method must be overridden in a subclass. The base +class supplies an argument list from which all Ice arguments +have already been removed. The method returns an integer +exit status (0 is success, non-zero is failure). +''' + raise RuntimeError('run() not implemented') + + def interruptCallback(self, sig): + '''Subclass hook to intercept an interrupt.''' + pass + + def appName(self): + '''Returns the application name (the first element of +the argument list).''' + return self._appName + appName = classmethod(appName) + + def communicator(self): + '''Returns the communicator that was initialized for +the application.''' + return self._communicator + communicator = classmethod(communicator) + + def destroyOnInterrupt(self): + '''Configures the application to destroy its communicator +when interrupted by a signal.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() == self._holdInterruptCallback: + self._released = True + self._condVar.notify() + self._ctrlCHandler.setCallback(self._destroyOnInterruptCallback) + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + destroyOnInterrupt = classmethod(destroyOnInterrupt) + + def shutdownOnInterrupt(self): + '''Configures the application to shutdown its communicator +when interrupted by a signal.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() == self._holdInterruptCallback: + self._released = True + self._condVar.notify() + self._ctrlCHandler.setCallback(self._shutdownOnInterruptCallback) + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + shutdownOnInterrupt = classmethod(shutdownOnInterrupt) + + def ignoreInterrupt(self): + '''Configures the application to ignore signals.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() == self._holdInterruptCallback: + self._released = True + self._condVar.notify() + self._ctrlCHandler.setCallback(None) + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + ignoreInterrupt = classmethod(ignoreInterrupt) + + def callbackOnInterrupt(self): + '''Configures the application to invoke interruptCallback +when interrupted by a signal.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() == self._holdInterruptCallback: + self._released = True + self._condVar.notify() + self._ctrlCHandler.setCallback(self._callbackOnInterruptCallback) + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + callbackOnInterrupt = classmethod(callbackOnInterrupt) + + def holdInterrupt(self): + '''Configures the application to queue an interrupt for +later processing.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() != self._holdInterruptCallback: + self._previousCallback = self._ctrlCHandler.getCallback() + self._released = False + self._ctrlCHandler.setCallback(self._holdInterruptCallback) + # else, we were already holding signals + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + holdInterrupt = classmethod(holdInterrupt) + + def releaseInterrupt(self): + '''Instructs the application to process any queued interrupt.''' + if Application._signalPolicy == Application.HandleSignals: + self._condVar.acquire() + if self._ctrlCHandler.getCallback() == self._holdInterruptCallback: + # + # Note that it's very possible no signal is held; + # in this case the callback is just replaced and + # setting _released to true and signalling _condVar + # do no harm. + # + self._released = True + self._ctrlCHandler.setCallback(self._previousCallback) + self._condVar.notify() + # Else nothing to release. + self._condVar.release() + else: + getProcessLogger().error(Application._appName + \ + ": warning: interrupt method called on Application configured to not handle interrupts.") + releaseInterrupt = classmethod(releaseInterrupt) + + def interrupted(self): + '''Returns True if the application was interrupted by a +signal, or False otherwise.''' + self._condVar.acquire() + result = self._interrupted + self._condVar.release() + return result + interrupted = classmethod(interrupted) + + def _holdInterruptCallback(self, sig): + self._condVar.acquire() + while not self._released: + self._condVar.wait() + if self._destroyed: + # + # Being destroyed by main thread + # + self._condVar.release() + return + callback = self._ctrlCHandler.getCallback() + self._condVar.release() + if callback: + callback(sig) + _holdInterruptCallback = classmethod(_holdInterruptCallback) + + def _destroyOnInterruptCallback(self, sig): + self._condVar.acquire() + if self._destroyed or self._nohup and sig == signal.SIGHUP: + # + # Being destroyed by main thread, or nohup. + # + self._condVar.release() + return + + self._callbackInProcess = True + self._interrupted = True + self._destroyed = True + self._condVar.release() + + try: + self._communicator.destroy() + except: + getProcessLogger().error(self._appName + " (while destroying in response to signal " + str(sig) + "):" + \ + traceback.format_exc()) + + self._condVar.acquire() + self._callbackInProcess = False + self._condVar.notify() + self._condVar.release() + _destroyOnInterruptCallback = classmethod(_destroyOnInterruptCallback) + + def _shutdownOnInterruptCallback(self, sig): + self._condVar.acquire() + if self._destroyed or self._nohup and sig == signal.SIGHUP: + # + # Being destroyed by main thread, or nohup. + # + self._condVar.release() + return + + self._callbackInProcess = True + self._interrupted = True + self._condVar.release() + + try: + self._communicator.shutdown() + except: + getProcessLogger().error(self._appName + " (while shutting down in response to signal " + str(sig) + \ + "):" + traceback.format_exc()) + + self._condVar.acquire() + self._callbackInProcess = False + self._condVar.notify() + self._condVar.release() + _shutdownOnInterruptCallback = classmethod(_shutdownOnInterruptCallback) + + def _callbackOnInterruptCallback(self, sig): + self._condVar.acquire() + if self._destroyed: + # + # Being destroyed by main thread. + # + self._condVar.release() + return + # For SIGHUP the user callback is always called. It can decide + # what to do. + + self._callbackInProcess = True + self._interrupted = True + self._condVar.release() + + try: + self._application.interruptCallback(sig) + except: + getProcessLogger().error(self._appName + " (while interrupting in response to signal " + str(sig) + \ + "):" + traceback.format_exc()) + + self._condVar.acquire() + self._callbackInProcess = False + self._condVar.notify() + self._condVar.release() + + _callbackOnInterruptCallback = classmethod(_callbackOnInterruptCallback) + + HandleSignals = 0 + NoSignalHandling = 1 + + _appName = None + _communicator = None + _application = None + _ctrlCHandler = None + _previousCallback = None + _interrupted = False + _released = False + _destroyed = False + _callbackInProgress = False + _condVar = threading.Condition() + _signalPolicy = HandleSignals + +# +# Define Ice::Object and Ice::ObjectPrx. +# +IcePy._t_Object = IcePy.defineClass('::Ice::Object', Object, -1, (), False, False, None, (), ()) +IcePy._t_ObjectPrx = IcePy.defineProxy('::Ice::Object', ObjectPrx) +Object._ice_type = IcePy._t_Object + +Object._op_ice_isA = IcePy.Operation('ice_isA', OperationMode.Idempotent, OperationMode.Nonmutating, False, None, (), (((), IcePy._t_string, False, 0),), (), ((), IcePy._t_bool, False, 0), ()) +Object._op_ice_ping = IcePy.Operation('ice_ping', OperationMode.Idempotent, OperationMode.Nonmutating, False, None, (), (), (), None, ()) +Object._op_ice_ids = IcePy.Operation('ice_ids', OperationMode.Idempotent, OperationMode.Nonmutating, False, None, (), (), (), ((), _t_StringSeq, False, 0), ()) +Object._op_ice_id = IcePy.Operation('ice_id', OperationMode.Idempotent, OperationMode.Nonmutating, False, None, (), (), (), ((), IcePy._t_string, False, 0), ()) + +IcePy._t_LocalObject = IcePy.defineClass('::Ice::LocalObject', object, -1, (), False, False, None, (), ()) + +IcePy._t_UnknownSlicedObject = IcePy.defineClass('::Ice::UnknownSlicedObject', UnknownSlicedObject, -1, (), False, True, None, (), ()) +UnknownSlicedObject._ice_type = IcePy._t_UnknownSlicedObject + +# +# Annotate some exceptions. +# +def SyscallException__str__(self): + return "Ice.SyscallException:\n" + os.strerror(self.error) +SyscallException.__str__ = SyscallException__str__ +del SyscallException__str__ + +def SocketException__str__(self): + return "Ice.SocketException:\n" + os.strerror(self.error) +SocketException.__str__ = SocketException__str__ +del SocketException__str__ + +def ConnectFailedException__str__(self): + return "Ice.ConnectFailedException:\n" + os.strerror(self.error) +ConnectFailedException.__str__ = ConnectFailedException__str__ +del ConnectFailedException__str__ + +def ConnectionRefusedException__str__(self): + return "Ice.ConnectionRefusedException:\n" + os.strerror(self.error) +ConnectionRefusedException.__str__ = ConnectionRefusedException__str__ +del ConnectionRefusedException__str__ + +def ConnectionLostException__str__(self): + if self.error == 0: + return "Ice.ConnectionLostException:\nrecv() returned zero" + else: + return "Ice.ConnectionLostException:\n" + os.strerror(self.error) +ConnectionLostException.__str__ = ConnectionLostException__str__ +del ConnectionLostException__str__ + +# +# Proxy comparison functions. +# +def proxyIdentityEqual(lhs, rhs): + '''Determines whether the identities of two proxies are equal.''' + return proxyIdentityCompare(lhs, rhs) == 0 + +def proxyIdentityCompare(lhs, rhs): + '''Compares the identities of two proxies.''' + if (lhs and not isinstance(lhs, ObjectPrx)) or (rhs and not isinstance(rhs, ObjectPrx)): + raise ValueError('argument is not a proxy') + if not lhs and not rhs: + return 0 + elif not lhs and rhs: + return -1 + elif lhs and not rhs: + return 1 + else: + lid = lhs.ice_getIdentity() + rid = rhs.ice_getIdentity() + return (lid > rid) - (lid < rid) + +def proxyIdentityAndFacetEqual(lhs, rhs): + '''Determines whether the identities and facets of two +proxies are equal.''' + return proxyIdentityAndFacetCompare(lhs, rhs) == 0 + +def proxyIdentityAndFacetCompare(lhs, rhs): + '''Compares the identities and facets of two proxies.''' + if (lhs and not isinstance(lhs, ObjectPrx)) or (rhs and not isinstance(rhs, ObjectPrx)): + raise ValueError('argument is not a proxy') + if not lhs and not rhs: + return 0 + elif not lhs and rhs: + return -1 + elif lhs and not rhs: + return 1 + elif lhs.ice_getIdentity() != rhs.ice_getIdentity(): + lid = lhs.ice_getIdentity() + rid = rhs.ice_getIdentity() + return (lid > rid) - (lid < rid) + else: + lf = lhs.ice_getFacet() + rf = rhs.ice_getFacet() + return (lf > rf) - (lf < rf) + +# +# Used by generated code. Defining these in the Ice module means the generated code +# can avoid the need to qualify the type() and hash() functions with their module +# names. Since the functions are in the __builtin__ module (for Python 2.x) and the +# builtins module (for Python 3.x), it's easier to define them here. +# +def getType(o): + return type(o) + +# +# Used by generated code. Defining this in the Ice module means the generated code +# can avoid the need to qualify the hash() function with its module name. Since +# the function is in the __builtin__ module (for Python 2.x) and the builtins +# module (for Python 3.x), it's easier to define it here. +# +def getHash(o): + return hash(o) + +Protocol_1_0 = ProtocolVersion(1, 0) +Encoding_1_0 = EncodingVersion(1, 0) +Encoding_1_1 = EncodingVersion(1, 1) diff --git a/python/python/Makefile b/python/python/Makefile new file mode 100644 index 00000000000..523aa4e9240 --- /dev/null +++ b/python/python/Makefile @@ -0,0 +1,155 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +# +# Parallel builds are not supported because multiple executions of slice2py could +# attempt to modify the __init__.py file simultaneously. +# +.NOTPARALLEL: + +ICE_SRCS = Ice_BuiltinSequences_ice.py \ + Ice_Communicator_ice.py \ + Ice_CommunicatorF_ice.py \ + Ice_Connection_ice.py \ + Ice_ConnectionF_ice.py \ + Ice_Current_ice.py \ + Ice_Endpoint_ice.py \ + Ice_EndpointF_ice.py \ + Ice_EndpointTypes_ice.py \ + Ice_FacetMap_ice.py \ + Ice_Identity_ice.py \ + Ice_ImplicitContext_ice.py \ + Ice_ImplicitContextF_ice.py \ + Ice_Instrumentation_ice.py \ + Ice_InstrumentationF_ice.py \ + Ice_LocalException_ice.py \ + Ice_Locator_ice.py \ + Ice_LocatorF_ice.py \ + Ice_Logger_ice.py \ + Ice_LoggerF_ice.py \ + Ice_Metrics_ice.py \ + Ice_ObjectAdapter_ice.py \ + Ice_ObjectAdapterF_ice.py \ + Ice_ObjectFactory_ice.py \ + Ice_ObjectFactoryF_ice.py \ + Ice_Plugin_ice.py \ + Ice_PluginF_ice.py \ + Ice_Process_ice.py \ + Ice_ProcessF_ice.py \ + Ice_Properties_ice.py \ + Ice_PropertiesAdmin_ice.py \ + Ice_PropertiesF_ice.py \ + Ice_Router_ice.py \ + Ice_RouterF_ice.py \ + Ice_ServantLocator_ice.py \ + Ice_ServantLocatorF_ice.py \ + Ice_SliceChecksumDict_ice.py \ + Ice_Version_ice.py + +GLACIER2_SRCS = Glacier2_Metrics_ice.py \ + Glacier2_PermissionsVerifier_ice.py \ + Glacier2_PermissionsVerifierF_ice.py \ + Glacier2_Router_ice.py \ + Glacier2_RouterF_ice.py \ + Glacier2_Session_ice.py \ + Glacier2_SSLInfo_ice.py + +ICEBOX_SRCS = IceBox_IceBox_ice.py + +ICEGRID_SRCS = IceGrid_Admin_ice.py \ + IceGrid_Descriptor_ice.py \ + IceGrid_Exception_ice.py \ + IceGrid_FileParser_ice.py \ + IceGrid_Locator_ice.py \ + IceGrid_Observer_ice.py \ + IceGrid_Query_ice.py \ + IceGrid_Registry_ice.py \ + IceGrid_Session_ice.py \ + IceGrid_UserAccountMapper_ice.py + +ICEPATCH2_SRCS = IcePatch2_FileInfo_ice.py \ + IcePatch2_FileServer_ice.py + +ICESTORM_SRCS = IceStorm_IceStorm_ice.py \ + IceStorm_Metrics_ice.py + +ALL_SRCS = $(ICE_SRCS) \ + $(GLACIER2_SRCS) \ + $(ICEBOX_SRCS) \ + $(ICEGRID_SRCS) \ + $(ICEPATCH2_SRCS) \ + $(ICESTORM_SRCS) + +ICE_SLICE = $(patsubst Ice_%_ice.py,$(slicedir)/Ice/%.ice,$(ICE_SRCS)) +GLACIER2_SLICE = $(patsubst Glacier2_%_ice.py,$(slicedir)/Glacier2/%.ice,$(GLACIER2_SRCS)) +ICEBOX_SLICE = $(patsubst IceBox_%_ice.py,$(slicedir)/IceBox/%.ice,$(ICEBOX_SRCS)) +ICEGRID_SLICE = $(patsubst IceGrid_%_ice.py,$(slicedir)/IceGrid/%.ice,$(ICEGRID_SRCS)) +ICEPATCH2_SLICE = $(patsubst IcePatch2_%_ice.py,$(slicedir)/IcePatch2/%.ice,$(ICEPATCH2_SRCS)) +ICESTORM_SLICE = $(patsubst IceStorm_%_ice.py,$(slicedir)/IceStorm/%.ice,$(ICESTORM_SRCS)) + +PACKAGES = IceBox IceGrid IcePatch2 IceStorm IceMX + +all:: $(ALL_SRCS) + +SLICE2PYFLAGS += --ice + +Ice_%_ice.py: $(slicedir)/Ice/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix Ice_ --no-package $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix Ice_ --no-package $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +Ice_Metrics_ice.py: $(slicedir)/Ice/Metrics.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix Ice_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix Ice_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +Glacier2_%_ice.py: $(slicedir)/Glacier2/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix Glacier2_ --no-package --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix Glacier2_ --no-package --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +Glacier2_Metrics_ice.py: $(slicedir)/Glacier2/Metrics.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix Glacier2_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix Glacier2_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +IceBox_%_ice.py: $(slicedir)/IceBox/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix IceBox_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix IceBox_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +IceGrid_%_ice.py: $(slicedir)/IceGrid/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix IceGrid_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix IceGrid_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +IcePatch2_%_ice.py: $(slicedir)/IcePatch2/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix IcePatch2_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix IcePatch2_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +IceStorm_%_ice.py: $(slicedir)/IceStorm/%.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) --prefix IceStorm_ --checksum $(SLICE2PYFLAGS) $< + @mkdir -p .depend + @$(SLICE2PY) --prefix IceStorm_ --checksum $(SLICE2PYFLAGS) --depend $< > .depend/$(*F).ice.d + +install:: $(ALL_SRCS) + @echo "Installing generated code" + $(INSTALL_DATA) *.py $(DESTDIR)$(install_pythondir) + @for i in $(PACKAGES) ; \ + do \ + $(INSTALL_DATA) -r $$i $(DESTDIR)$(install_pythondir) ; \ + done + +clean:: + rm -rf $(PACKAGES) *_ice.py diff --git a/python/python/Makefile.mak b/python/python/Makefile.mak new file mode 100644 index 00000000000..cf85d359037 --- /dev/null +++ b/python/python/Makefile.mak @@ -0,0 +1,357 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +!include $(top_srcdir)\config\Make.rules.mak + +ICE_SDIR = Ice + +ICE_SLICES = Ice\BuiltinSequences.ice \ + Ice\Communicator.ice \ + Ice\CommunicatorF.ice \ + Ice\Connection.ice \ + Ice\ConnectionF.ice \ + Ice\Current.ice \ + Ice\Endpoint.ice \ + Ice\EndpointF.ice \ + Ice\EndpointTypes.ice \ + Ice\FacetMap.ice \ + Ice\Identity.ice \ + Ice\ImplicitContext.ice \ + Ice\ImplicitContextF.ice \ + Ice\Instrumentation.ice \ + Ice\InstrumentationF.ice \ + Ice\LocalException.ice \ + Ice\Locator.ice \ + Ice\LocatorF.ice \ + Ice\Logger.ice \ + Ice\LoggerF.ice \ + Ice\Metrics.ice \ + Ice\ObjectAdapter.ice \ + Ice\ObjectAdapterF.ice \ + Ice\ObjectFactory.ice \ + Ice\ObjectFactoryF.ice \ + Ice\Plugin.ice \ + Ice\PluginF.ice \ + Ice\Process.ice \ + Ice\ProcessF.ice \ + Ice\Properties.ice \ + Ice\PropertiesAdmin.ice \ + Ice\PropertiesF.ice \ + Ice\Router.ice \ + Ice\RouterF.ice \ + Ice\ServantLocator.ice \ + Ice\ServantLocatorF.ice \ + Ice\SliceChecksumDict.ice \ + Ice\Version.ice \ + +ICE_SRCS = $(ICE_SLICES:.ice=_ice.py) +ICE_SRCS = $(ICE_SRCS:Ice\=Ice_) + +GLACIER2_SDIR = Glacier2 + +GLACIER2_SLICES = Glacier2\Metrics.ice \ + Glacier2\PermissionsVerifier.ice \ + Glacier2\PermissionsVerifierF.ice \ + Glacier2\Router.ice \ + Glacier2\RouterF.ice \ + Glacier2\Session.ice \ + Glacier2\SSLInfo.ice \ + +GLACIER2_SRCS = $(GLACIER2_SLICES:.ice=_ice.py) +GLACIER2_SRCS = $(GLACIER2_SRCS:Glacier2\=Glacier2_) + +ICEBOX_SDIR = IceBox + +ICEBOX_SLICES = IceBox\IceBox.ice +ICEBOX_SRCS = $(ICEBOX_SLICES:.ice=_ice.py) +ICEBOX_SRCS = $(ICEBOX_SRCS:IceBox\=IceBox_) + +ICEGRID_SDIR = IceGrid + +ICEGRID_SLICES = IceGrid\Admin.ice \ + IceGrid\Descriptor.ice \ + IceGrid\Exception.ice \ + IceGrid\FileParser.ice \ + IceGrid\Locator.ice \ + IceGrid\Observer.ice \ + IceGrid\Query.ice \ + IceGrid\Registry.ice \ + IceGrid\Session.ice \ + IceGrid\UserAccountMapper.ice \ + +ICEGRID_SRCS = $(ICEGRID_SLICES:.ice=_ice.py) +ICEGRID_SRCS = $(ICEGRID_SRCS:IceGrid\=IceGrid_) + +ICEPATCH2_SDIR = IcePatch2 + +ICEPATCH2_SLICES = IcePatch2\FileInfo.ice \ + IcePatch2\FileServer.ice + +ICEPATCH2_SRCS = $(ICEPATCH2_SLICES:.ice=_ice.py) +ICEPATCH2_SRCS = $(ICEPATCH2_SRCS:IcePatch2\=IcePatch2_) + +ICESTORM_SDIR = IceStorm + +ICESTORM_SLICES = IceStorm\Metrics.ice \ + IceStorm\IceStorm.ice + +ICESTORM_SRCS = $(ICESTORM_SLICES:.ice=_ice.py) +ICESTORM_SRCS = $(ICESTORM_SRCS:IceStorm\=IceStorm_) + +DEPENDS = $(ICE_SLICES:.ice=.d) \ + $(GLACIER2_SLICES:.ice=.d) \ + $(ICEBOX_SLICES:.ice=.d) \ + $(ICEGRID_SLICES:.ice=.d) \ + $(ICEPATCH2_SLICES:.ice=.d) \ + $(ICESTORM_SLICES:.ice=.d) + +ALL_SRCS = $(ICE_SRCS) \ + $(GLACIER2_SRCS) \ + $(ICEBOX_SRCS) \ + $(ICEGRID_SRCS) \ + $(ICEPATCH2_SRCS) \ + $(ICESTORM_SRCS) + +PACKAGES = IceBox IceGrid IcePatch2 IceStorm IceMX + +SLICE2PYFLAGS = $(SLICE2PYFLAGS) --ice + +all:: $(ALL_SRCS) + +depend:: + del /q .depend.mak + +{$(slicedir)\$(ICE_SDIR)\}.ice{$(ICE_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix Ice_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +{$(slicedir)\$(GLACIER2_SDIR)\}.ice{$(GLACIER2_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix Glacier2_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +{$(slicedir)\$(ICEBOX_SDIR)\}.ice{$(ICEBOX_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix IceBox_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +{$(slicedir)\$(ICEGRID_SDIR)\}.ice{$(ICEGRID_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix IceGrid_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +{$(slicedir)\$(ICEPATCH2_SDIR)\}.ice{$(ICEPATCH2_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix IcePatch2_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +{$(slicedir)\$(ICESTORM_SDIR)\}.ice{$(ICESTORM_SDIR)\}.d: + @echo Generating dependencies for $< + @"$(SLICE2PY)" --prefix IceStorm_ --no-package $(SLICE2PYFLAGS) --depend "$<" | \ + cscript /NoLogo $(top_srcdir)\..\config\makedepend-slice.vbs $(*F).ice + +depend:: $(DEPENDS) + +Ice_LocalException_ice.py: "$(slicedir)/Ice/LocalException.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/LocalException.ice" + +Ice_Communicator_ice.py: "$(slicedir)/Ice/Communicator.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Communicator.ice" + +Ice_CommunicatorF_ice.py: "$(slicedir)/Ice/CommunicatorF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/CommunicatorF.ice" + +Ice_Logger_ice.py: "$(slicedir)/Ice/Logger.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Logger.ice" + +Ice_LoggerF_ice.py: "$(slicedir)/Ice/LoggerF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/LoggerF.ice" + +Ice_BuiltinSequences_ice.py: "$(slicedir)/Ice/BuiltinSequences.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/BuiltinSequences.ice" + +Ice_ObjectAdapter_ice.py: "$(slicedir)/Ice/ObjectAdapter.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ObjectAdapter.ice" + +Ice_ObjectAdapterF_ice.py: "$(slicedir)/Ice/ObjectAdapterF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ObjectAdapterF.ice" + +Ice_ServantLocator_ice.py: "$(slicedir)/Ice/ServantLocator.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ServantLocator.ice" + +Ice_ServantLocatorF_ice.py: "$(slicedir)/Ice/ServantLocatorF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ServantLocatorF.ice" + +Ice_PropertiesAdmin_ice.py: "$(slicedir)/Ice/PropertiesAdmin.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/PropertiesAdmin.ice" + +Ice_Properties_ice.py: "$(slicedir)/Ice/Properties.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Properties.ice" + +Ice_PropertiesF_ice.py: "$(slicedir)/Ice/PropertiesF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/PropertiesF.ice" + +Ice_ObjectFactory_ice.py: "$(slicedir)/Ice/ObjectFactory.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ObjectFactory.ice" + +Ice_ObjectFactoryF_ice.py: "$(slicedir)/Ice/ObjectFactoryF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ObjectFactoryF.ice" + +Ice_Identity_ice.py: "$(slicedir)/Ice/Identity.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Identity.ice" + +Ice_Current_ice.py: "$(slicedir)/Ice/Current.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Current.ice" + +Ice_ImplicitContext_ice.py: "$(slicedir)/Ice/ImplicitContext.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ImplicitContext.ice" + +Ice_ImplicitContextF_ice.py: "$(slicedir)/Ice/ImplicitContextF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ImplicitContextF.ice" + +Ice_Router_ice.py: "$(slicedir)/Ice/Router.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Router.ice" + +Ice_RouterF_ice.py: "$(slicedir)/Ice/RouterF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/RouterF.ice" + +Ice_Plugin_ice.py: "$(slicedir)/Ice/Plugin.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Plugin.ice" + +Ice_PluginF_ice.py: "$(slicedir)/Ice/PluginF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/PluginF.ice" + +Ice_Locator_ice.py: "$(slicedir)/Ice/Locator.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Locator.ice" + +Ice_LocatorF_ice.py: "$(slicedir)/Ice/LocatorF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/LocatorF.ice" + +Ice_Process_ice.py: "$(slicedir)/Ice/Process.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Process.ice" + +Ice_ProcessF_ice.py: "$(slicedir)/Ice/ProcessF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ProcessF.ice" + +Ice_FacetMap_ice.py: "$(slicedir)/Ice/FacetMap.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/FacetMap.ice" + +Ice_Connection_ice.py: "$(slicedir)/Ice/Connection.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Connection.ice" + +Ice_ConnectionF_ice.py: "$(slicedir)/Ice/ConnectionF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/ConnectionF.ice" + +Ice_SliceChecksumDict_ice.py: "$(slicedir)/Ice/SliceChecksumDict.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/SliceChecksumDict.ice" + +Ice_Endpoint_ice.py: "$(slicedir)/Ice/Endpoint.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Endpoint.ice" + +Ice_EndpointF_ice.py: "$(slicedir)/Ice/EndpointF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/EndpointF.ice" + +Ice_EndpointTypes_ice.py: "$(slicedir)/Ice/EndpointTypes.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/EndpointTypes.ice" + +Ice_Version_ice.py: "$(slicedir)/Ice/Version.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Version.ice" + +Ice_Instrumentation_ice.py: "$(slicedir)/Ice/Instrumentation.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/Instrumentation.ice" + +Ice_InstrumentationF_ice.py: "$(slicedir)/Ice/InstrumentationF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package "$(slicedir)/Ice/InstrumentationF.ice" + +Ice_Metrics_ice.py: "$(slicedir)/Ice/Metrics.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Ice_ --no-package --checksum "$(slicedir)/Ice/Metrics.ice" + +Glacier2_RouterF_ice.py: "$(slicedir)/Glacier2/RouterF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/RouterF.ice" + +Glacier2_Router_ice.py: "$(slicedir)/Glacier2/Router.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/Router.ice" + +Glacier2_Session_ice.py: "$(slicedir)/Glacier2/Session.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/Session.ice" + +Glacier2_PermissionsVerifierF_ice.py: "$(slicedir)/Glacier2/PermissionsVerifierF.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/PermissionsVerifierF.ice" + +Glacier2_PermissionsVerifier_ice.py: "$(slicedir)/Glacier2/PermissionsVerifier.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/PermissionsVerifier.ice" + +Glacier2_SSLInfo_ice.py: "$(slicedir)/Glacier2/SSLInfo.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/SSLInfo.ice" + +Glacier2_Metrics_ice.py: "$(slicedir)/Glacier2/Metrics.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix Glacier2_ --no-package --checksum "$(slicedir)/Glacier2/Metrics.ice" + +IceBox_IceBox_ice.py: "$(slicedir)/IceBox/IceBox.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceBox_ --checksum "$(slicedir)/IceBox/IceBox.ice" + +IceGrid_Admin_ice.py: "$(slicedir)/IceGrid/Admin.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Admin.ice" + +IceGrid_Descriptor_ice.py: "$(slicedir)/IceGrid/Descriptor.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Descriptor.ice" + +IceGrid_Exception_ice.py: "$(slicedir)/IceGrid/Exception.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Exception.ice" + +IceGrid_FileParser_ice.py: "$(slicedir)/IceGrid/FileParser.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/FileParser.ice" + +IceGrid_Locator_ice.py: "$(slicedir)/IceGrid/Locator.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Locator.ice" + +IceGrid_Observer_ice.py: "$(slicedir)/IceGrid/Observer.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Observer.ice" + +IceGrid_Query_ice.py: "$(slicedir)/IceGrid/Query.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Query.ice" + +IceGrid_Registry_ice.py: "$(slicedir)/IceGrid/Registry.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Registry.ice" + +IceGrid_Session_ice.py: "$(slicedir)/IceGrid/Session.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/Session.ice" + +IceGrid_UserAccountMapper_ice.py: "$(slicedir)/IceGrid/UserAccountMapper.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceGrid_ --checksum "$(slicedir)/IceGrid/UserAccountMapper.ice" + +IcePatch2_FileInfo_ice.py: "$(slicedir)/IcePatch2/FileInfo.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IcePatch2_ --checksum "$(slicedir)/IcePatch2/FileInfo.ice" + +IcePatch2_FileServer_ice.py: "$(slicedir)/IcePatch2/FileServer.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IcePatch2_ --checksum "$(slicedir)/IcePatch2/FileServer.ice" + +IceStorm_IceStorm_ice.py: "$(slicedir)/IceStorm/IceStorm.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceStorm_ --checksum "$(slicedir)/IceStorm/IceStorm.ice" + +IceStorm_Metrics_ice.py: "$(slicedir)/IceStorm/Metrics.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) --prefix IceStorm_ --checksum "$(slicedir)/IceStorm/Metrics.ice" + +install:: $(ALL_SRCS) + @echo "Installing generated code" + copy *.py "$(install_pythondir)" + @for %i in ( $(PACKAGES) ) do \ + @if not exist "$(install_pythondir)\%i" \ + mkdir "$(install_pythondir)\%i" + @for %i in ( $(PACKAGES) ) do \ + copy %i\* "$(install_pythondir)\%i" + +clean:: + -rmdir /s /q $(PACKAGES) + del /q *_ice.py + +#include .depend.mak diff --git a/python/test/Ice/acm/AllTests.py b/python/test/Ice/acm/AllTests.py new file mode 100644 index 00000000000..6cfae071a24 --- /dev/null +++ b/python/test/Ice/acm/AllTests.py @@ -0,0 +1,399 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading, time, traceback + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class LoggerI(Ice.Logger): + def __init__(self): + self._started = False + self._messages = [] + self.m = threading.Lock() + + def start(self): + self.m.acquire() + try: + self._started = True + self.dump() + finally: + self.m.release() + + def _print(self, msg): + self.m.acquire() + try: + self._messages.append(msg) + if self._started: + self.dump() + finally: + self.m.release() + + def trace(self, category, msg): + self.m.acquire() + try: + self._messages.append("[" + category + "] " + msg) + if self._started: + self.dump() + finally: + self.m.release() + + def warning(self, msg): + self.m.acquire() + try: + self._messages.append("warning: " + msg) + if self._started: + self.dump() + finally: + self.m.release() + + def error(self, msg): + self.m.acquire() + try: + self._messages.append("error: " + msg) + if self._started: + self.dump() + finally: + self.m.release() + + def getPrefix(self): + return "" + + def cloneWithPrefix(self, prefix): + return self + + def dump(self): + for p in self._messages: + print(p) + self._messages = [] + +class TestCase(threading.Thread, Ice.ConnectionCallback): + def __init__(self, name, com): + threading.Thread.__init__(self) + self._name = name + self._com = com + self._logger = LoggerI() + self._clientACMTimeout = -1 + self._clientACMClose = -1 + self._clientACMHeartbeat = -1 + self._serverACMTimeout = -1 + self._serverACMClose = -1 + self._serverACMHeartbeat = -1 + self._heartbeat = 0 + self._closed = False + self._msg = "" + self.m = threading.Lock() + + def init(self): + self._adapter = \ + self._com.createObjectAdapter(self._serverACMTimeout, self._serverACMClose, self._serverACMHeartbeat) + + initData = Ice.InitializationData() + initData.properties = self._com.ice_getCommunicator().getProperties().clone() + initData.logger = self._logger + initData.properties.setProperty("Ice.ACM.Timeout", "1") + if self._clientACMTimeout >= 0: + initData.properties.setProperty("Ice.ACM.Client.Timeout", str(self._clientACMTimeout)) + if self._clientACMClose >= 0: + initData.properties.setProperty("Ice.ACM.Client.Close", str(self._clientACMClose)) + if self._clientACMHeartbeat >= 0: + initData.properties.setProperty("Ice.ACM.Client.Heartbeat", str(self._clientACMHeartbeat)) + #initData.properties.setProperty("Ice.Trace.Protocol", "2") + #initData.properties.setProperty("Ice.Trace.Network", "2") + self._communicator = Ice.initialize(initData) + + def destroy(self): + self._adapter.deactivate() + self._communicator.destroy() + + def joinWithThread(self): + sys.stdout.write("testing " + self._name + "... ") + sys.stdout.flush() + self._logger.start() + self.join() + if len(self._msg) == 0: + print("ok") + else: + print("failed!\n" + self._msg) + test(False) + + def run(self): + proxy = Test.TestIntfPrx.uncheckedCast(self._communicator.stringToProxy( + self._adapter.getTestIntf().ice_toString())) + try: + proxy.ice_getConnection().setCallback(self) + self.runTestCase(self._adapter, proxy) + except Exception as ex: + self._msg = "unexpected exception:\n" + traceback.format_exc() + + def heartbeat(self, con): + self.m.acquire() + try: + self._heartbeat = self._heartbeat + 1 + finally: + self.m.release() + + def closed(self, con): + self.m.acquire() + try: + self._closed = True + finally: + self.m.release() + + def runTestCase(self, adapter, proxy): + test(False) + + def setClientACM(self, timeout, close, heartbeat): + self._clientACMTimeout = timeout + self._clientACMClose = close + self._clientACMHeartbeat = heartbeat + + def setServerACM(self, timeout, close, heartbeat): + self._serverACMTimeout = timeout + self._serverACMClose = close + self._serverACMHeartbeat = heartbeat + +def allTests(communicator): + ref = "communicator:default -p 12010" + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)) + + tests = [] + + class InvocationHeartbeatTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "invocation heartbeat", com) + + def runTestCase(self, adapter, proxy): + proxy.sleep(2) + + self.m.acquire() + try: + test(self._heartbeat >= 2) + finally: + self.m.release() + + class InvocationHeartbeatOnHoldTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "invocation with heartbeat on hold", com) + # Use default ACM configuration. + + def runTestCase(self, adapter, proxy): + try: + # When the OA is put on hold, connections shouldn't + # send heartbeats, the invocation should therefore + # fail. + proxy.sleepAndHold(10) + test(False) + except Ice.ConnectionTimeoutException: + adapter.activate() + proxy.interruptSleep() + + self.m.acquire() + try: + test(self._closed) + finally: + self.m.release() + + class InvocationNoHeartbeatTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "invocation with no heartbeat", com) + self.setServerACM(1, 2, 0) # Disable heartbeat on invocations + + def runTestCase(self, adapter, proxy): + try: + # Heartbeats are disabled on the server, the + # invocation should fail since heartbeats are + # expected. + proxy.sleep(10) + test(False) + except Ice.ConnectionTimeoutException: + proxy.interruptSleep() + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(self._closed) + finally: + self.m.release() + + class InvocationHeartbeatCloseOnIdleTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "invocation with no heartbeat and close on idle", com) + self.setClientACM(1, 1, 0) # Only close on idle. + self.setServerACM(1, 2, 0) # Disable heartbeat on invocations + + def runTestCase(self, adapter, proxy): + # No close on invocation, the call should succeed this time. + proxy.sleep(2) + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(not self._closed) + finally: + self.m.release() + + class CloseOnIdleTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "close on idle", com) + self.setClientACM(1, 1, 0) # Only close on idle. + + def runTestCase(self, adapter, proxy): + time.sleep(1.6) # Idle for 1.6 seconds + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(self._closed) + finally: + self.m.release() + + class CloseOnInvocationTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "close on invocation", com) + self.setClientACM(1, 2, 0) # Only close on invocation. + + def runTestCase(self, adapter, proxy): + time.sleep(1.5) # Idle for 1.5 seconds + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(not self._closed) + finally: + self.m.release() + + class CloseOnIdleAndInvocationTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "close on idle and invocation", com) + self.setClientACM(1, 3, 0) # Only close on idle and invocation. + + def runTestCase(self, adapter, proxy): + # + # Put the adapter on hold. The server will not respond to + # the graceful close. This allows to test whether or not + # the close is graceful or forceful. + # + adapter.hold() + time.sleep(1.6) # Idle for 1.6 seconds + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(not self._closed) # Not closed yet because of graceful close. + finally: + self.m.release() + + adapter.activate() + time.sleep(0.5) + + self.m.acquire() + try: + test(self._closed) # Connection should be closed this time. + finally: + self.m.release() + + class ForcefulCloseOnIdleAndInvocationTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "forceful close on idle and invocation", com) + self.setClientACM(1, 4, 0) # Only close on idle and invocation. + + def runTestCase(self, adapter, proxy): + adapter.hold() + time.sleep(1.6) # Idle for 1.6 seconds + + self.m.acquire() + try: + test(self._heartbeat == 0) + test(self._closed) # Connection closed forcefully by ACM. + finally: + self.m.release() + + class HeartbeatOnIdleTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "heartbeat on idle", com) + self.setServerACM(1, -1, 2) # Enable server heartbeats. + + def runTestCase(self, adapter, proxy): + time.sleep(2) + + self.m.acquire() + try: + test(self._heartbeat >= 3) + finally: + self.m.release() + + class HeartbeatAlwaysTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "heartbeat always", com) + self.setServerACM(1, -1, 3) # Enable server heartbeats. + + def runTestCase(self, adapter, proxy): + for i in range(0, 20): + proxy.ice_ping() + time.sleep(0.1) + + self.m.acquire() + try: + test(self._heartbeat >= 3) + finally: + self.m.release() + + class SetACMTest(TestCase): + def __init__(self, com): + TestCase.__init__(self, "setACM/getACM", com) + self.setClientACM(15, 4, 2) + + def runTestCase(self, adapter, proxy): + acm = proxy.ice_getCachedConnection().getACM() + test(acm.timeout == 15) + test(acm.close == Ice.ACMClose.CloseOnIdleForceful) + test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOnIdle) + + proxy.ice_getCachedConnection().setACM(Ice.Unset, Ice.Unset, Ice.Unset) + acm = proxy.ice_getCachedConnection().getACM() + test(acm.timeout == 15) + test(acm.close == Ice.ACMClose.CloseOnIdleForceful) + test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOnIdle) + + proxy.ice_getCachedConnection().setACM(20, Ice.ACMClose.CloseOnInvocationAndIdle, + Ice.ACMHeartbeat.HeartbeatOnInvocation) + acm = proxy.ice_getCachedConnection().getACM() + test(acm.timeout == 20) + test(acm.close == Ice.ACMClose.CloseOnInvocationAndIdle) + test(acm.heartbeat == Ice.ACMHeartbeat.HeartbeatOnInvocation) + + tests.append(InvocationHeartbeatTest(com)) + tests.append(InvocationHeartbeatOnHoldTest(com)) + tests.append(InvocationNoHeartbeatTest(com)) + tests.append(InvocationHeartbeatCloseOnIdleTest(com)) + + tests.append(CloseOnIdleTest(com)) + tests.append(CloseOnInvocationTest(com)) + tests.append(CloseOnIdleAndInvocationTest(com)) + tests.append(ForcefulCloseOnIdleAndInvocationTest(com)) + + tests.append(HeartbeatOnIdleTest(com)) + tests.append(HeartbeatAlwaysTest(com)) + tests.append(SetACMTest(com)) + + for p in tests: + p.init() + for p in tests: + p.start() + for p in tests: + p.joinWithThread() + for p in tests: + p.destroy() + + sys.stdout.write("shutting down... ") + sys.stdout.flush() + com.shutdown() + print("ok") diff --git a/python/test/Ice/acm/Client.py b/python/test/Ice/acm/Client.py new file mode 100755 index 00000000000..2c49777617b --- /dev/null +++ b/python/test/Ice/acm/Client.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty('Ice.Warn.Connections', '0') + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/acm/Server.py b/python/test/Ice/acm/Server.py new file mode 100755 index 00000000000..1f63722fe09 --- /dev/null +++ b/python/test/Ice/acm/Server.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + communicator.getProperties().setProperty("TestAdapter.ACM.Timeout", "0") + adapter = communicator.createObjectAdapter("TestAdapter") + id = communicator.stringToIdentity("communicator") + adapter.add(TestI.RemoteCommunicatorI(), id) + adapter.activate() + + # Disable ready print for further adapters. + communicator.getProperties().setProperty("Ice.PrintAdapterReady", "0") + + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Connections", "0"); + initData.properties.setProperty("Ice.ACM.Timeout", "1"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/acm/Test.ice b/python/test/Ice/acm/Test.ice new file mode 100644 index 00000000000..b1c8b749109 --- /dev/null +++ b/python/test/Ice/acm/Test.ice @@ -0,0 +1,37 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + void sleep(int seconds); + void sleepAndHold(int seconds); + void interruptSleep(); +}; + +interface RemoteObjectAdapter +{ + TestIntf* getTestIntf(); + void activate(); + void hold(); + void deactivate(); +}; + +interface RemoteCommunicator +{ + RemoteObjectAdapter* createObjectAdapter(int acmTimeout, int close, int heartbeat); + void shutdown(); +}; + +}; + diff --git a/python/test/Ice/acm/TestI.py b/python/test/Ice/acm/TestI.py new file mode 100644 index 00000000000..6b63fd26d07 --- /dev/null +++ b/python/test/Ice/acm/TestI.py @@ -0,0 +1,78 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, threading + +class RemoteCommunicatorI(Test.RemoteCommunicator): + def createObjectAdapter(self, timeout, close, heartbeat, current=None): + com = current.adapter.getCommunicator() + properties = com.getProperties() + protocol = properties.getPropertyWithDefault("Ice.Default.Protocol", "tcp"); + + name = Ice.generateUUID() + if timeout >= 0: + properties.setProperty(name + ".ACM.Timeout", str(timeout)) + if close >= 0: + properties.setProperty(name + ".ACM.Close", str(close)) + if heartbeat >= 0: + properties.setProperty(name + ".ACM.Heartbeat", str(heartbeat)) + properties.setProperty(name + ".ThreadPool.Size", "2") + adapter = com.createObjectAdapterWithEndpoints(name, protocol + " -h 127.0.0.1") + return Test.RemoteObjectAdapterPrx.uncheckedCast(current.adapter.addWithUUID(RemoteObjectAdapterI(adapter))) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +class RemoteObjectAdapterI(Test.RemoteObjectAdapter): + def __init__(self, adapter): + self._adapter = adapter + self._testIntf = Test.TestIntfPrx.uncheckedCast(adapter.add(TestIntfI(), + adapter.getCommunicator().stringToIdentity("test"))) + adapter.activate() + + def getTestIntf(self, current=None): + return self._testIntf + + def activate(self, current=None): + self._adapter.activate() + + def hold(self, current=None): + self._adapter.hold() + + def deactivate(self, current=None): + try: + self._adapter.destroy() + except Ice.ObjectAdapterDeactivatedException: + pass + +class TestIntfI(Test.TestIntf): + def __init__(self): + self.m = threading.Condition() + + def sleep(self, delay, current=None): + self.m.acquire() + try: + self.m.wait(delay) + finally: + self.m.release() + + def sleepAndHold(self, delay, current=None): + self.m.acquire() + try: + current.adapter.hold() + self.m.wait(delay) + finally: + self.m.release() + + def interruptSleep(self, delay, current=None): + self.m.acquire() + try: + self.m.notifyAll() + finally: + self.m.release() diff --git a/python/test/Ice/acm/run.py b/python/test/Ice/acm/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/acm/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/adapterDeactivation/AllTests.py b/python/test/Ice/adapterDeactivation/AllTests.py new file mode 100644 index 00000000000..db92fedbd02 --- /dev/null +++ b/python/test/Ice/adapterDeactivation/AllTests.py @@ -0,0 +1,72 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + base = communicator.stringToProxy("test:default -p 12010") + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + obj = Test.TestIntfPrx.checkedCast(base) + test(obj) + test(obj == base) + print("ok") + + sys.stdout.write("creating/destroying/recreating object adapter... ") + sys.stdout.flush() + adapter = communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", "default") + try: + communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", "default") + test(False) + except Ice.LocalException: + pass + adapter.destroy() + + adapter = communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", "default") + adapter.destroy() + print("ok") + + sys.stdout.write("creating/activating/deactivating object adapter in one operation... ") + sys.stdout.flush() + obj.transient() + print("ok") + + sys.stdout.write("deactivating object adapter in the server... ") + sys.stdout.flush() + obj.deactivate() + print("ok") + + sys.stdout.write("testing connection closure... "); + sys.stdout.flush(); + for x in range(10): + initData = Ice.InitializationData(); + initData.properties = communicator.getProperties().clone(); + comm = Ice.initialize(initData); + comm.stringToProxy("test:default -p 12010").begin_ice_ping(); + comm.destroy(); + print("ok"); + + sys.stdout.write("testing whether server is gone... ") + sys.stdout.flush() + try: + obj.ice_ping() + test(False) + except Ice.LocalException: + print("ok") + + return obj diff --git a/python/test/Ice/adapterDeactivation/Client.py b/python/test/Ice/adapterDeactivation/Client.py new file mode 100755 index 00000000000..a7aa744ec0a --- /dev/null +++ b/python/test/Ice/adapterDeactivation/Client.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +import Ice +Ice.loadSlice('Test.ice') +import Test, AllTests + +class TestClient(Ice.Application): + def run(self, args): + AllTests.allTests(self.communicator()) + return 0 + +app = TestClient() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/adapterDeactivation/Collocated.py b/python/test/Ice/adapterDeactivation/Collocated.py new file mode 100755 index 00000000000..c27c1c0915a --- /dev/null +++ b/python/test/Ice/adapterDeactivation/Collocated.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI, AllTests + +class TestServer(Ice.Application): + def run(self, args): + self.communicator().getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = self.communicator().createObjectAdapter("TestAdapter") + locator = TestI.ServantLocatorI() + + adapter.addServantLocator(locator, "") + #adapter.activate() // Don't activate OA to ensure collocation is used. + + AllTests.allTests(self.communicator()) + + adapter.waitForDeactivate() + return 0 + +app = TestServer() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/adapterDeactivation/Server.py b/python/test/Ice/adapterDeactivation/Server.py new file mode 100755 index 00000000000..53c39294ad3 --- /dev/null +++ b/python/test/Ice/adapterDeactivation/Server.py @@ -0,0 +1,28 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI + +class TestServer(Ice.Application): + def run(self, args): + self.communicator().getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = self.communicator().createObjectAdapter("TestAdapter") + locator = TestI.ServantLocatorI() + + adapter.addServantLocator(locator, "") + adapter.activate() + adapter.waitForDeactivate() + return 0 + +app = TestServer() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/adapterDeactivation/Test.ice b/python/test/Ice/adapterDeactivation/Test.ice new file mode 100644 index 00000000000..7e9fecd5f89 --- /dev/null +++ b/python/test/Ice/adapterDeactivation/Test.ice @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + void transient(); + + void deactivate(); +}; + +local class Cookie +{ + idempotent string message(); +}; + +}; diff --git a/python/test/Ice/adapterDeactivation/TestI.py b/python/test/Ice/adapterDeactivation/TestI.py new file mode 100644 index 00000000000..3b61867c0ba --- /dev/null +++ b/python/test/Ice/adapterDeactivation/TestI.py @@ -0,0 +1,56 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time +import Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestI(Test.TestIntf): + def transient(self, current=None): + communicator = current.adapter.getCommunicator() + adapter = communicator.createObjectAdapterWithEndpoints("TransientTestAdapter", "default -p 9999") + adapter.activate() + adapter.destroy() + + def deactivate(self, current=None): + current.adapter.deactivate() + time.sleep(0.1) + +class CookieI(Test.Cookie): + def message(self): + return 'blahblah' + +class ServantLocatorI(Ice.ServantLocator): + def __init__(self): + self._deactivated = False + + def __del__(self): + test(self._deactivated) + + def locate(self, current): + test(not self._deactivated) + + test(current.id.category == '') + test(current.id.name == 'test') + + return (TestI(), CookieI()) + + def finished(self, current, servant, cookie): + test(not self._deactivated) + + test(isinstance(cookie, Test.Cookie)) + test(cookie.message() == 'blahblah') + + def deactivate(self, category): + test(not self._deactivated) + + self._deactivated = True diff --git a/python/test/Ice/adapterDeactivation/run.py b/python/test/Ice/adapterDeactivation/run.py new file mode 100755 index 00000000000..9487c74a4f5 --- /dev/null +++ b/python/test/Ice/adapterDeactivation/run.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() +TestUtil.collocatedTest() diff --git a/python/test/Ice/admin/AllTests.py b/python/test/Ice/admin/AllTests.py new file mode 100644 index 00000000000..c76a7d65325 --- /dev/null +++ b/python/test/Ice/admin/AllTests.py @@ -0,0 +1,347 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, TestI + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def testFacets(com, builtInFacets = True): + + if builtInFacets: + test(com.findAdminFacet("Properties") != None) + test(com.findAdminFacet("Process") != None) + test(com.findAdminFacet("Logger") != None) + test(com.findAdminFacet("Metrics") != None) + + f1 = TestI.TestFacetI() + f2 = TestI.TestFacetI() + f3 = TestI.TestFacetI() + + com.addAdminFacet(f1, "Facet1") + com.addAdminFacet(f2, "Facet2") + com.addAdminFacet(f3, "Facet3") + + test(com.findAdminFacet("Facet1") == f1) + test(com.findAdminFacet("Facet2") == f2) + test(com.findAdminFacet("Facet3") == f3) + test(com.findAdminFacet("Bogus") == None) + + facetMap = com.findAllAdminFacets() + if builtInFacets: + test(len(facetMap) == 7) + test("Properties" in facetMap) + test(isinstance(facetMap["Properties"], Ice.NativePropertiesAdmin)) + test("Process" in facetMap) + test("Logger" in facetMap) + test("Metrics" in facetMap) + + test(len(facetMap) >=3) + + test("Facet1" in facetMap) + test("Facet2" in facetMap) + test("Facet3" in facetMap) + + try: + com.addAdminFacet(f1, "Facet1") + test(False) + except Ice.AlreadyRegisteredException: + pass # Expected + + try: + com.removeAdminFacet("Bogus") + test(False) + except Ice.NotRegisteredException: + pass # Expected + + com.removeAdminFacet("Facet1") + com.removeAdminFacet("Facet2") + com.removeAdminFacet("Facet3") + + try: + com.removeAdminFacet("Facet1") + test(False) + except Ice.NotRegisteredException: + pass # Expected + + +def allTests(communicator): + sys.stdout.write("testing communicator operations... ") + sys.stdout.flush() + + # + # Test: Exercise addAdminFacet, findAdminFacet, removeAdminFacet with a typical configuration. + # + init = Ice.InitializationData() + init.properties = Ice.createProperties() + init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1") + init.properties.setProperty("Ice.Admin.InstanceName", "Test") + init.properties.setProperty("Ice.ProgramName", "MyTestProgram") + com = Ice.initialize(init) + testFacets(com) + test(com.getLogger().getPrefix() == "MyTestProgram") + com.destroy() + + # + # Test: Verify that the operations work correctly in the presence of facet filters. + # + init = Ice.InitializationData() + init.properties = Ice.createProperties() + init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1") + init.properties.setProperty("Ice.Admin.InstanceName", "Test") + init.properties.setProperty("Ice.Admin.Facets", "Properties") + com = Ice.initialize(init) + testFacets(com, False) + com.destroy() + + # + # Test: Verify that the operations work correctly with the Admin object disabled. + # + com = Ice.initialize() + testFacets(com, False) + com.destroy() + + # + # Test: Verify that the operations work correctly when Ice.Admin is enabled. + # + init = Ice.InitializationData() + init.properties = Ice.createProperties() + init.properties.setProperty("Ice.Admin.Enabled", "1") + com = Ice.initialize(init) + test(com.getAdmin() == None) + identity = com.stringToIdentity("test-admin") + try: + com.createAdmin(None, identity) + test(False) + except Ice.InitializationException: + pass + + adapter = com.createObjectAdapter("") + test(com.createAdmin(adapter, identity) != None) + test(com.getAdmin() != None) + + testFacets(com) + com.destroy() + + # + # Test: Verify that the operations work correctly when creation of the Admin object is delayed. + # + init = Ice.InitializationData() + init.properties = Ice.createProperties() + init.properties.setProperty("Ice.Admin.Endpoints", "tcp -h 127.0.0.1") + init.properties.setProperty("Ice.Admin.InstanceName", "Test") + init.properties.setProperty("Ice.Admin.DelayCreation", "1") + com = Ice.initialize(init) + testFacets(com) + com.getAdmin() + testFacets(com) + com.destroy() + print("ok") + + ref = "factory:default -p 12010 -t 10000" + factory = Test.RemoteCommunicatorFactoryPrx.uncheckedCast(communicator.stringToProxy(ref)) + + sys.stdout.write("testing process facet... ") + sys.stdout.flush() + + # + # Test: Verify that Process::shutdown() operation shuts down the communicator. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + com = factory.createCommunicator(props) + obj = com.getAdmin() + proc = Ice.ProcessPrx.checkedCast(obj, "Process") + proc.shutdown() + com.waitForShutdown() + com.destroy() + + print("ok") + + sys.stdout.write("testing properties facet... ") + sys.stdout.flush() + + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Prop1"] = "1" + props["Prop2"] = "2" + props["Prop3"] = "3" + com = factory.createCommunicator(props) + obj = com.getAdmin() + pa = Ice.PropertiesAdminPrx.checkedCast(obj, "Properties") + + # + # Test: PropertiesAdmin::getProperty() + # + test(pa.getProperty("Prop2") == "2") + test(pa.getProperty("Bogus") == "") + + # + # Test: PropertiesAdmin::getProperties() + # + pd = pa.getPropertiesForPrefix("") + test(len(pd) == 5) + test(pd["Ice.Admin.Endpoints"] == "tcp -h 127.0.0.1") + test(pd["Ice.Admin.InstanceName"] == "Test") + test(pd["Prop1"] == "1") + test(pd["Prop2"] == "2") + test(pd["Prop3"] == "3") + + changes = {} + + # + # Test: PropertiesAdmin::setProperties() + # + setProps = {} + setProps["Prop1"] = "10" # Changed + setProps["Prop2"] = "20" # Changed + setProps["Prop3"] = "" # Removed + setProps["Prop4"] = "4" # Added + setProps["Prop5"] = "5" # Added + pa.setProperties(setProps) + test(pa.getProperty("Prop1") == "10") + test(pa.getProperty("Prop2") == "20") + test(pa.getProperty("Prop3") == "") + test(pa.getProperty("Prop4") == "4") + test(pa.getProperty("Prop5") == "5") + changes = com.getChanges() + test(len(changes) == 5) + test(changes["Prop1"] == "10") + test(changes["Prop2"] == "20") + test(changes["Prop3"] == "") + test(changes["Prop4"] == "4") + test(changes["Prop5"] == "5") + pa.setProperties(setProps) + changes = com.getChanges() + test(len(changes) == 0) + + com.destroy() + + print("ok") + + sys.stdout.write("testing custom facet... ") + sys.stdout.flush() + + # + # Test: Verify that the custom facet is present. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + com = factory.createCommunicator(props) + obj = com.getAdmin() + tf = Test.TestFacetPrx.checkedCast(obj, "TestFacet") + tf.op() + com.destroy() + + print("ok") + + sys.stdout.write("testing facet filtering... ") + sys.stdout.flush() + + # + # Test: Set Ice.Admin.Facets to expose only the Properties facet, + # meaning no other facet is available. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Ice.Admin.Facets"] = "Properties" + com = factory.createCommunicator(props) + obj = com.getAdmin() + + proc = Ice.ProcessPrx.checkedCast(obj, "Process") + test(proc == None) + tf = Test.TestFacetPrx.checkedCast(obj, "TestFacet") + test(tf == None) + com.destroy() + + # + # Test: Set Ice.Admin.Facets to expose only the Process facet, + # meaning no other facet is available. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Ice.Admin.Facets"] = "Process" + com = factory.createCommunicator(props) + obj = com.getAdmin() + + pa = Ice.PropertiesAdminPrx.checkedCast(obj, "Properties") + test(pa == None) + tf = Test.TestFacetPrx.checkedCast(obj, "TestFacet") + test(tf == None) + + com.destroy() + + # + # Test: Set Ice.Admin.Facets to expose only the TestFacet facet, + # meaning no other facet is available. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Ice.Admin.Facets"] = "TestFacet" + com = factory.createCommunicator(props) + obj = com.getAdmin() + + pa = Ice.PropertiesAdminPrx.checkedCast(obj, "Properties") + test(pa == None) + + proc = Ice.ProcessPrx.checkedCast(obj, "Process") + test(proc == None) + + com.destroy() + + # + # Test: Set Ice.Admin.Facets to expose two facets. Use whitespace to separate the + # facet names. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Ice.Admin.Facets"] = "Properties TestFacet" + com = factory.createCommunicator(props) + obj = com.getAdmin() + pa = Ice.PropertiesAdminPrx.checkedCast(obj, "Properties") + test(pa.getProperty("Ice.Admin.InstanceName") == "Test") + tf = Test.TestFacetPrx.checkedCast(obj, "TestFacet") + tf.op() + + proc = Ice.ProcessPrx.checkedCast(obj, "Process") + test(proc == None) + com.destroy() + + # + # Test: Set Ice.Admin.Facets to expose two facets. Use a comma to separate the + # facet names. + # + props = {} + props["Ice.Admin.Endpoints"] = "tcp -h 127.0.0.1" + props["Ice.Admin.InstanceName"] = "Test" + props["Ice.Admin.Facets"] = "TestFacet, Process" + com = factory.createCommunicator(props) + obj = com.getAdmin() + + pa = Ice.PropertiesAdminPrx.checkedCast(obj, "Properties") + test(pa == None) + + tf = Test.TestFacetPrx.checkedCast(obj, "TestFacet") + tf.op() + proc = Ice.ProcessPrx.checkedCast(obj, "Process") + proc.shutdown() + com.waitForShutdown() + com.destroy() + + print("ok") + + factory.shutdown() diff --git a/python/test/Ice/admin/Client.py b/python/test/Ice/admin/Client.py new file mode 100644 index 00000000000..9a4a8071b56 --- /dev/null +++ b/python/test/Ice/admin/Client.py @@ -0,0 +1,44 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice + +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/admin/Server.py b/python/test/Ice/admin/Server.py new file mode 100644 index 00000000000..a310310cc19 --- /dev/null +++ b/python/test/Ice/admin/Server.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice + +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000"); + adapter = communicator.createObjectAdapter("TestAdapter"); + ident = communicator.stringToIdentity("factory"); + adapter.add(TestI.RemoteCommunicatorFactoryI(), ident); + adapter.activate(); + + communicator.waitForShutdown(); + return True; + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/admin/Test.ice b/python/test/Ice/admin/Test.ice new file mode 100644 index 00000000000..92d1cf94e49 --- /dev/null +++ b/python/test/Ice/admin/Test.ice @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#ifndef TEST_ICE +#define TEST_ICE + +#include <Ice/Properties.ice> + +module Test +{ + +interface RemoteCommunicator +{ + Object* getAdmin(); + + Ice::PropertyDict getChanges(); + + void shutdown(); + + void waitForShutdown(); + + void destroy(); +}; + +interface RemoteCommunicatorFactory +{ + RemoteCommunicator* createCommunicator(Ice::PropertyDict props); + + void shutdown(); +}; + +interface TestFacet +{ + void op(); +}; + +}; + +#endif diff --git a/python/test/Ice/admin/TestI.py b/python/test/Ice/admin/TestI.py new file mode 100644 index 00000000000..f1f6f8880ea --- /dev/null +++ b/python/test/Ice/admin/TestI.py @@ -0,0 +1,105 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestFacetI(Test.TestFacet): + def op(self, current = None): + return + +class RemoteCommunicatorI(Test.RemoteCommunicator, Ice.PropertiesAdminUpdateCallback): + def __init__(self, communicator): + self.communicator = communicator + self.called = False + self.m = threading.Condition() + + def getAdmin(self, current = None): + return self.communicator.getAdmin() + + def getChanges(self, current = None): + self.m.acquire() + try: + # + # The client calls PropertiesAdmin::setProperties() and then invokes + # this operation. Since setProperties() is implemented using AMD, the + # client might receive its reply and then call getChanges() before our + # updated() method is called. We block here to ensure that updated() + # gets called before we return the most recent set of changes. + # + while not self.called: + self.m.wait() + + self.called = False + + return self.changes + finally: + self.m.release() + + def shutdown(self, current = None): + self.communicator.shutdown() + + def waitForShutdown(self, current = None): + # + # Note that we are executing in a thread of the *main* communicator, + # not the one that is being shut down. + # + self.communicator.waitForShutdown() + + def destroy(self, current = None): + self.communicator.destroy() + + def updated(self, changes): + self.m.acquire() + try: + self.changes = changes + self.called = True + self.m.notify() + finally: + self.m.release() + +class RemoteCommunicatorFactoryI(Test.RemoteCommunicatorFactory): + + def createCommunicator(self, props, current = None): + # + # Prepare the property set using the given properties. + # + init = Ice.InitializationData() + init.properties = Ice.createProperties() + for k, v in props.items(): + init.properties.setProperty(k, v) + + # + # Initialize a new communicator. + # + communicator = Ice.initialize(init) + + # + # Install a custom admin facet. + # + communicator.addAdminFacet(TestFacetI(), "TestFacet") + + # + # The RemoteCommunicator servant also implements PropertiesAdminUpdateCallback. + # Set the callback on the admin facet. + # + servant = RemoteCommunicatorI(communicator) + admin = communicator.findAdminFacet("Properties") + if admin != None: + admin.addUpdateCallback(servant) + + proxy = current.adapter.addWithUUID(servant) + return Test.RemoteCommunicatorPrx.uncheckedCast(proxy) + + def shutdown(self, current = None): + current.adapter.getCommunicator().shutdown() + diff --git a/python/test/Ice/admin/run.py b/python/test/Ice/admin/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/admin/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/ami/AllTests.py b/python/test/Ice/ami/AllTests.py new file mode 100644 index 00000000000..93d7d9573ba --- /dev/null +++ b/python/test/Ice/ami/AllTests.py @@ -0,0 +1,1090 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading, random + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + + def exception(self, ex): + test(False) + +class ResponseCallback(CallbackBase): + def isA(self, r): + test(r) + self.called() + + def ping(self): + self.called() + + def id(self, id): + test(id == "::Test::TestIntf") + self.called() + + def ids(self, ids): + test(len(ids) == 2) + self.called() + + def connection(self, conn): + test(conn != None) + self.called() + + def op(self): + self.called() + + def opWithResult(self, r): + test(r == 15) + self.called() + + def opWithUE(self, ex): + try: + raise ex + except Test.TestIntfException: + self.called() + except: + test(False) + + def ex(self, ex): + pass + +class ResponseCallbackWC(CallbackBase): + def __init__(self, cookie): + CallbackBase.__init__(self) + self._cookie = cookie + + def isA(self, r, cookie): + test(cookie == self._cookie) + test(r) + self.called() + + def ping(self, cookie): + test(cookie == self._cookie) + self.called() + + def id(self, id, cookie): + test(cookie == self._cookie) + test(id == "::Test::TestIntf") + self.called() + + def ids(self, ids, cookie): + test(cookie == self._cookie) + test(len(ids) == 2) + self.called() + + def connection(self, conn, cookie): + test(cookie == self._cookie) + test(conn != None) + self.called() + + def op(self, cookie): + test(cookie == self._cookie) + self.called() + + def opWithResult(self, r, cookie): + test(cookie == self._cookie) + test(r == 15) + self.called() + + def opWithUE(self, ex, cookie): + test(cookie == self._cookie) + try: + raise ex + except Test.TestIntfException: + self.called() + except: + test(False) + + def ex(self, ex, cookie): + pass + +class ExceptionCallback(CallbackBase): + def response(self, *args): + test(False) + + def nullResponse(self, *args): + pass + + def opWithUE(self, ex): + test(isinstance(ex, Test.TestIntfException)) + self.called() + + def ex(self, ex): + test(isinstance(ex, Ice.NoEndpointException)) + self.called() + + def noEx(self, ex): + test(False) + +class ExceptionCallbackWC(CallbackBase): + def __init__(self, cookie): + CallbackBase.__init__(self) + self._cookie = cookie + + def response(self, *args): + test(False) + + def nullResponse(self, *args): + pass + + def opWithUE(self, ex, cookie): + test(cookie == self._cookie) + test(isinstance(ex, Test.TestIntfException)) + self.called() + + def ex(self, ex, cookie): + test(cookie == self._cookie) + test(isinstance(ex, Ice.NoEndpointException)) + self.called() + + def noEx(self, ex, cookie): + test(False) + +class SentCallback(CallbackBase): + def __init__(self): + CallbackBase.__init__(self) + self._thread = threading.currentThread() + + def response(self, *args): + pass + + def ex(self, ex): + pass + + def sent(self, sentSynchronously): + test((sentSynchronously and self._thread == threading.currentThread()) or \ + (not sentSynchronously and self._thread != threading.currentThread())) + self.called() + +class SentCallbackWC(CallbackBase): + def __init__(self, cookie): + CallbackBase.__init__(self) + self._thread = threading.currentThread() + self._cookie = cookie + + def response(self, *args): + pass + + def ex(self, ex, cookie): + pass + + def sent(self, sentSynchronously, cookie): + test(cookie == self._cookie) + test((sentSynchronously and self._thread == threading.currentThread()) or \ + (not sentSynchronously and self._thread != threading.currentThread())) + self.called() + +class FlushCallback(CallbackBase): + def __init__(self, cookie=None): + CallbackBase.__init__(self) + self._thread = threading.currentThread() + self._cookie = cookie + + def exception(self, ex): + test(False) + + def exceptionWC(self, ex, cookie): + test(False) + + def sent(self, sentSynchronously): + test((sentSynchronously and self._thread == threading.currentThread()) or \ + (not sentSynchronously and self._thread != threading.currentThread())) + self.called() + + def sentWC(self, sentSynchronously, cookie): + test((sentSynchronously and self._thread == threading.currentThread()) or \ + (not sentSynchronously and self._thread != threading.currentThread())) + test(cookie == self._cookie) + self.called() + +class FlushExCallback(CallbackBase): + def __init__(self, cookie=None): + CallbackBase.__init__(self) + self._cookie = cookie + + def exception(self, ex): + self.called() + + def exceptionWC(self, ex, cookie): + test(cookie == self._cookie) + self.called() + + def sent(self, sentSynchronously): + test(False) + + def sentWC(self, sentSynchronously, cookie): + test(False) + +LocalException = 0 +UserException = 1 +OtherException = 2 + +def throwEx(t): + if t == LocalException: + raise Ice.ObjectNotExistException() + elif t == UserException: + raise Test.TestIntfException() + elif t == OtherException: + raise RuntimeError() + else: + test(False) + +class Thrower(CallbackBase): + def __init__(self, t): + CallbackBase.__init__(self) + self._t = t + + def op(self): + self.called() + throwEx(self._t) + + def opWC(self, cookie): + self.called() + throwEx(self._t) + + def noOp(self): + pass + + def noOpWC(self, cookie): + pass + + def ex(self, ex): + self.called() + throwEx(self._t) + + def exWC(self, ex, cookie): + self.called() + throwEx(self._t) + + def noEx(self, ex): + test(False) + + def noExWC(self, ex, cookie): + test(False) + + def sent(self, ss): + self.called() + throwEx(self._t) + + def sentWC(self, ss, cookie): + self.called() + throwEx(self._t) + +def allTests(communicator, collocated): + sref = "test:default -p 12010" + obj = communicator.stringToProxy(sref) + test(obj) + + p = Test.TestIntfPrx.uncheckedCast(obj) + + sref = "testController:default -p 12011" + obj = communicator.stringToProxy(sref) + test(obj) + + testController = Test.TestIntfControllerPrx.uncheckedCast(obj) + + sys.stdout.write("testing begin/end invocation... ") + sys.stdout.flush() + ctx = {} + + result = p.begin_ice_isA("::Test::TestIntf") + test(p.end_ice_isA(result)) + result = p.begin_ice_isA("::Test::TestIntf", _ctx=ctx) + test(p.end_ice_isA(result)) + + result = p.begin_ice_ping() + p.end_ice_ping(result) + result = p.begin_ice_ping(_ctx=ctx) + p.end_ice_ping(result) + + result = p.begin_ice_id() + test(p.end_ice_id(result) == "::Test::TestIntf") + result = p.begin_ice_id(_ctx=ctx) + test(p.end_ice_id(result) == "::Test::TestIntf") + + result = p.begin_ice_ids() + test(len(p.end_ice_ids(result)) == 2) + result = p.begin_ice_ids(_ctx=ctx) + test(len(p.end_ice_ids(result)) == 2) + + if not collocated: + result = p.begin_ice_getConnection() + test(p.end_ice_getConnection(result) != None) + + result = p.begin_op() + p.end_op(result) + result = p.begin_op(_ctx=ctx) + p.end_op(result) + + result = p.begin_opWithResult() + test(p.end_opWithResult(result) == 15) + result = p.begin_opWithResult(_ctx=ctx) + test(p.end_opWithResult(result) == 15) + + result = p.begin_opWithUE() + try: + p.end_opWithUE(result) + test(False) + except Test.TestIntfException: + pass + result = p.begin_opWithUE(_ctx=ctx) + try: + p.end_opWithUE(result) + test(False) + except Test.TestIntfException: + pass + + print("ok") + + sys.stdout.write("testing response callback... ") + sys.stdout.flush() + + ctx = {} + cb = ResponseCallback() + cookie = 5 + cbWC = ResponseCallbackWC(cookie) + + p.begin_ice_isA(Test.TestIntf.ice_staticId(), cb.isA, cb.ex) + cb.check() + p.begin_ice_isA(Test.TestIntf.ice_staticId(), lambda r: cbWC.isA(r, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_ice_isA(Test.TestIntf.ice_staticId(), cb.isA, cb.ex, _ctx=ctx) + cb.check() + p.begin_ice_isA(Test.TestIntf.ice_staticId(), lambda r: cbWC.isA(r, cookie), lambda ex: cbWC.ex(ex, cookie), + _ctx=ctx) + cbWC.check() + + p.begin_ice_ping(cb.ping, cb.ex) + cb.check() + p.begin_ice_ping(lambda: cbWC.ping(cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_ice_ping(cb.ping, cb.ex, _ctx=ctx) + cb.check() + p.begin_ice_ping(lambda: cbWC.ping(cookie), lambda: cbWC.ex(ex, cookie), _ctx=ctx) + cbWC.check() + + p.begin_ice_id(cb.id, cb.ex) + cb.check() + p.begin_ice_id(lambda id: cbWC.id(id, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_ice_id(cb.id, cb.ex, _ctx=ctx) + cb.check() + p.begin_ice_id(lambda id: cbWC.id(id, cookie), lambda ex: cbWC.ex(ex, cookie), _ctx=ctx) + cbWC.check() + + p.begin_ice_ids(cb.ids, cb.ex) + cb.check() + p.begin_ice_ids(lambda ids: cbWC.ids(ids, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_ice_ids(cb.ids, cb.ex, _ctx=ctx) + cb.check() + p.begin_ice_ids(lambda ids: cbWC.ids(ids, cookie), lambda ex: cbWC.ex(ex, cookie), _ctx=ctx) + cbWC.check() + + if not collocated: + p.begin_ice_getConnection(cb.connection, cb.ex) + cb.check() + p.begin_ice_getConnection(lambda conn: cbWC.connection(conn, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + p.begin_op(cb.op, cb.ex) + cb.check() + p.begin_op(lambda: cbWC.op(cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_op(cb.op, cb.ex, _ctx=ctx) + cb.check() + p.begin_op(lambda: cbWC.op(cookie), lambda ex: cbWC.ex(ex, cookie), _ctx=ctx) + cbWC.check() + + p.begin_opWithResult(cb.opWithResult, cb.ex) + cb.check() + p.begin_opWithResult(lambda r: cbWC.opWithResult(r, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + p.begin_opWithResult(cb.opWithResult, cb.ex, _ctx=ctx) + cb.check() + p.begin_opWithResult(lambda r: cbWC.opWithResult(r, cookie), lambda ex: cbWC.ex(ex, cookie), _ctx=ctx) + cbWC.check() + + p.begin_opWithUE(cb.op, cb.opWithUE) + cb.check() + p.begin_opWithUE(lambda: cbWC.op(cookie), lambda ex: cbWC.opWithUE(ex, cookie)) + cbWC.check() + p.begin_opWithUE(cb.op, cb.opWithUE, _ctx=ctx) + cb.check() + p.begin_opWithUE(lambda: cbWC.op(cookie), lambda ex: cbWC.opWithUE(ex, cookie), _ctx=ctx) + cbWC.check() + + print("ok") + + sys.stdout.write("testing local exceptions... ") + sys.stdout.flush() + + indirect = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy")) + + r = indirect.begin_op() + try: + indirect.end_op(r) + test(False) + except Ice.NoEndpointException: + pass + + try: + p.ice_oneway().begin_opWithResult() + test(False) + except RuntimeError: + pass + + # + # Check that CommunicatorDestroyedException is raised directly. + # + if p.ice_getConnection(): + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + ic = Ice.initialize(initData) + obj = ic.stringToProxy(p.ice_toString()) + p2 = Test.TestIntfPrx.checkedCast(obj) + ic.destroy(); + + try: + p2.begin_op() + test(False) + except Ice.CommunicatorDestroyedException: + pass + + print("ok") + + sys.stdout.write("testing local exceptions with response callback... ") + sys.stdout.flush() + + i = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy")) + cb = ExceptionCallback() + cookie = 5 + cbWC = ExceptionCallbackWC(cookie) + + i.begin_ice_isA(Test.TestIntf.ice_staticId(), cb.response, cb.ex) + cb.check() + i.begin_ice_isA(Test.TestIntf.ice_staticId(), lambda b: cbWC.response(b, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + i.begin_ice_ping(cb.response, cb.ex) + cb.check() + i.begin_ice_ping(lambda: cbWC.response(cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + i.begin_ice_id(cb.response, cb.ex) + cb.check() + i.begin_ice_id(lambda id: cbWC.response(id, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + i.begin_ice_ids(cb.response, cb.ex) + cb.check() + i.begin_ice_ids(lambda ids: cbWC.response(ids, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + if not collocated: + i.begin_ice_getConnection(cb.response, cb.ex) + cb.check() + i.begin_ice_getConnection(lambda conn: cbWC.response(conn, cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + i.begin_op(cb.response, cb.ex) + cb.check() + i.begin_op(lambda: cbWC.response(cookie), lambda ex: cbWC.ex(ex, cookie)) + cbWC.check() + + print("ok") + + sys.stdout.write("testing exception callback... ") + sys.stdout.flush() + + cb = ExceptionCallback() + cookie = 5 + cbWC = ExceptionCallbackWC(cookie) + + # Ensures no exception is called when response is received. + p.begin_ice_isA(Test.TestIntf.ice_staticId(), cb.nullResponse, cb.noEx) + p.begin_ice_isA(Test.TestIntf.ice_staticId(), lambda b: cbWC.nullResponse(b, cookie), + lambda ex: cbWC.noEx(ex, cookie)) + p.begin_op(cb.nullResponse, cb.noEx) + p.begin_op(lambda: cbWC.nullResponse(cookie), lambda ex: cbWC.noEx(ex, cookie)) + + # If response is a user exception, it should be received. + p.begin_opWithUE(cb.nullResponse, cb.opWithUE) + cb.check() + p.begin_opWithUE(lambda: cbWC.nullResponse(cookie), lambda ex: cbWC.opWithUE(ex, cookie)) + cbWC.check() + + print("ok") + + sys.stdout.write("testing sent callback... ") + sys.stdout.flush() + + cb = SentCallback() + cookie = 5 + cbWC = SentCallbackWC(cookie) + + p.begin_ice_isA("", cb.response, cb.ex, cb.sent) + cb.check() + p.begin_ice_isA("", lambda b: cbWC.response(b, cookie), lambda ex: cbWC.ex(ex, cookie), + lambda ss: cbWC.sent(ss, cookie)) + cbWC.check() + + p.begin_ice_ping(cb.response, cb.ex, cb.sent) + cb.check() + p.begin_ice_ping(lambda: cbWC.response(cookie), lambda ex: cbWC.ex(ex, cookie), lambda ss: cbWC.sent(ss, cookie)) + cbWC.check() + + p.begin_ice_id(cb.response, cb.ex, cb.sent) + cb.check() + p.begin_ice_id(lambda id: cbWC.response(id, cookie), lambda ex: cbWC.ex(ex, cookie), + lambda ss: cbWC.sent(ss, cookie)) + cbWC.check() + + p.begin_ice_ids(cb.response, cb.ex, cb.sent) + cb.check() + p.begin_ice_ids(lambda ids: cbWC.response(ids, cookie), lambda ex: cbWC.ex(ex, cookie), + lambda ss: cbWC.sent(ss, cookie)) + cbWC.check() + + p.begin_op(cb.response, cb.ex, cb.sent) + cb.check() + p.begin_op(lambda: cbWC.response(cookie), lambda ex: cbWC.ex(ex, cookie), lambda ss: cbWC.sent(ss, cookie)) + cbWC.check() + + cbs = [] + if sys.version_info[0] == 2: + b = [chr(random.randint(0, 255)) for x in range(0, 1024)] + seq = ''.join(b) + else: + b = [random.randint(0, 255) for x in range(0, 1024)] + seq = bytes(b) + testController.holdAdapter() + try: + cb = SentCallback() + while(p.begin_opWithPayload(seq, None, cb.ex, cb.sent).sentSynchronously()): + cbs.append(cb) + cb = SentCallback() + except Exception as ex: + testController.resumeAdapter() + raise ex + testController.resumeAdapter() + for r in cbs: + r.check() + + print("ok") + + sys.stdout.write("testing illegal arguments... ") + sys.stdout.flush() + + result = p.begin_op() + p.end_op(result) + try: + p.end_op(result) + test(False) + except RuntimeError: + pass + + result = p.begin_op() + try: + p.end_opWithResult(result) + test(False) + except RuntimeError: + pass + + print("ok") + + sys.stdout.write("testing unexpected exceptions from callback... ") + sys.stdout.flush() + + q = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy")) + throwTypes = [ LocalException, UserException, OtherException ] + + for t in throwTypes: + cb = Thrower(t) + cookie = 5 + + p.begin_op(cb.op, cb.noEx) + cb.check() + + p.begin_op(lambda: cb.opWC(cookie), lambda ex: cb.noExWC(ex, cookie)) + cb.check() + + q.begin_op(cb.op, cb.ex) + cb.check() + + q.begin_op(lambda: cb.opWC(cookie), lambda ex: cb.exWC(ex, cookie)) + cb.check() + + p.begin_op(cb.noOp, cb.ex, cb.sent) + cb.check() + + p.begin_op(lambda: cb.noOpWC(cookie), lambda ex: cb.exWC(ex, cookie), lambda ss: cb.sentWC(ss, cookie)) + cb.check() + + q.begin_op(None, cb.ex) + cb.check() + + q.begin_op(None, lambda ex: cb.exWC(ex, cookie)) + cb.check() + + print("ok") + + sys.stdout.write("testing batch requests with proxy... ") + sys.stdout.flush() + + cookie = 5 + + # + # Without cookie. + # + test(p.opBatchCount() == 0) + b1 = p.ice_batchOneway() + b1.opBatch() + b1.opBatch() + cb = FlushCallback() + r = b1.begin_ice_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) + test(r.isCompleted()) + test(p.waitForBatch(2)) + + # + # With cookie. + # + test(p.opBatchCount() == 0) + b1 = p.ice_batchOneway() + b1.opBatch() + b1.opBatch() + cb = FlushCallback(cookie) + r = b1.begin_ice_flushBatchRequests(lambda ex: cb.exceptionWC(ex, cookie), lambda ss: cb.sentWC(ss, cookie)) + cb.check() + test(p.waitForBatch(2)) + + if p.ice_getConnection(): # No collocation optimization + # + # Exception without cookie. + # + test(p.opBatchCount() == 0) + b1 = p.ice_batchOneway() + b1.opBatch() + b1.ice_getConnection().close(False) + cb = FlushCallback() + r = b1.begin_ice_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) + test(r.isCompleted()) + test(p.waitForBatch(1)) + + # + # Exception with cookie. + # + test(p.opBatchCount() == 0) + b1 = p.ice_batchOneway() + b1.opBatch() + b1.ice_getConnection().close(False) + cb = FlushCallback(cookie) + r = b1.begin_ice_flushBatchRequests(lambda ex: cb.exceptionWC(ex, cookie), lambda ss: cb.sentWC(ss, cookie)) + cb.check() + test(p.waitForBatch(1)) + + print("ok") + + if p.ice_getConnection(): # No collocation optimization + sys.stdout.write("testing batch requests with connection... ") + sys.stdout.flush() + + cookie = 5 + + # + # Without cookie. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.opBatch() + cb = FlushCallback() + r = b1.ice_getConnection().begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) + test(r.isCompleted()) + test(p.waitForBatch(2)) + + # + # With cookie. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.opBatch() + cb = FlushCallback(cookie) + r = b1.ice_getConnection().begin_flushBatchRequests(lambda ex: cb.exceptionWC(ex, cookie), + lambda ss: cb.sentWC(ss, cookie)) + cb.check() + test(p.waitForBatch(2)) + + # + # Exception without cookie. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.ice_getConnection().close(False) + cb = FlushExCallback() + r = b1.ice_getConnection().begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(not r.isSent()) + test(r.isCompleted()) + test(p.opBatchCount() == 0) + + # + # Exception with cookie. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.ice_getConnection().close(False) + cb = FlushExCallback(cookie) + r = b1.ice_getConnection().begin_flushBatchRequests(lambda ex: cb.exceptionWC(ex, cookie), + lambda ss: cb.sentWC(ss, cookie)) + cb.check() + test(p.opBatchCount() == 0) + + print("ok") + + sys.stdout.write("testing batch requests with communicator... ") + sys.stdout.flush() + + # + # 1 connection. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.opBatch() + cb = FlushCallback() + r = communicator.begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) + test(r.isCompleted()) + test(p.waitForBatch(2)) + + # + # 1 connection. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b1.opBatch() + b1.ice_getConnection().close(False) + cb = FlushCallback() + r = communicator.begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) # Exceptions are ignored! + test(r.isCompleted()) + test(p.opBatchCount() == 0) + + # + # 2 connections. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy( + p.ice_getIdentity()).ice_batchOneway()) + b2.ice_getConnection() # Ensure connection is established. + b1.opBatch() + b1.opBatch() + b2.opBatch() + b2.opBatch() + cb = FlushCallback() + r = communicator.begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) + test(r.isCompleted()) + test(p.waitForBatch(4)) + + # + # 2 connections - 1 failure. + # + # All connections should be flushed even if there are failures on some connections. + # Exceptions should not be reported. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy( + p.ice_getIdentity()).ice_batchOneway()) + b2.ice_getConnection() # Ensure connection is established. + b1.opBatch() + b2.opBatch() + b1.ice_getConnection().close(False) + cb = FlushCallback() + r = communicator.begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) # Exceptions are ignored! + test(r.isCompleted()) + test(p.waitForBatch(1)) + + # + # 2 connections - 2 failures. + # + # The sent callback should be invoked even if all connections fail. + # + test(p.opBatchCount() == 0) + b1 = Test.TestIntfPrx.uncheckedCast(p.ice_getConnection().createProxy(p.ice_getIdentity()).ice_batchOneway()) + b2 = Test.TestIntfPrx.uncheckedCast(p.ice_connectionId("2").ice_getConnection().createProxy( + p.ice_getIdentity()).ice_batchOneway()) + b2.ice_getConnection() # Ensure connection is established. + b1.opBatch() + b2.opBatch() + b1.ice_getConnection().close(False) + b2.ice_getConnection().close(False) + cb = FlushCallback() + r = communicator.begin_flushBatchRequests(cb.exception, cb.sent) + cb.check() + test(r.isSent()) # Exceptions are ignored! + test(r.isCompleted()) + test(p.opBatchCount() == 0) + + print("ok") + + sys.stdout.write("testing AsyncResult operations... ") + sys.stdout.flush() + + indirect = Test.TestIntfPrx.uncheckedCast(p.ice_adapterId("dummy")) + r = indirect.begin_op() + try: + r.waitForCompleted() + r.throwLocalException() + test(False) + except Ice.NoEndpointException: + pass + + testController.holdAdapter() + r1 = None + r2 = None + try: + r1 = p.begin_op() + if sys.version_info[0] == 2: + b = [chr(random.randint(0, 255)) for x in range(0, 1024)] + seq = ''.join(b) + else: + b = [random.randint(0, 255) for x in range(0, 1024)] + seq = bytes(b) + while(True): + r2 = p.begin_opWithPayload(seq) + if not r2.sentSynchronously(): + break + + test(r1 == r1) + test(r1 != r2) + + if p.ice_getConnection(): + test((r1.sentSynchronously() and r1.isSent() and not r1.isCompleted()) or + (not r1.sentSynchronously() and not r1.isCompleted())); + + test(not r2.sentSynchronously() and not r2.isCompleted()); + except Exception as ex: + testController.resumeAdapter() + raise ex + testController.resumeAdapter() + + r1.waitForSent() + test(r1.isSent()) + + r2.waitForSent() + test(r2.isSent()) + + r1.waitForCompleted() + test(r1.isCompleted()) + + r2.waitForCompleted() + test(r2.isCompleted()) + + test(r1.getOperation() == "op") + test(r2.getOperation() == "opWithPayload") + + # + # Twoway + # + r = p.begin_ice_ping() + test(r.getOperation() == "ice_ping") + test(r.getConnection() == None) # Expected + test(r.getCommunicator() == communicator) + test(r.getProxy() == p) + p.end_ice_ping(r) + + # + # Oneway + # + p2 = p.ice_oneway() + r = p2.begin_ice_ping() + test(r.getOperation() == "ice_ping") + test(r.getConnection() == None) # Expected + test(r.getCommunicator() == communicator) + test(r.getProxy() == p2) + + # + # Batch request via proxy + # + p2 = p.ice_batchOneway() + p2.ice_ping() + r = p2.begin_ice_flushBatchRequests() + test(r.getConnection() == None) # Expected + test(r.getCommunicator() == communicator) + test(r.getProxy() == p2) + p2.end_ice_flushBatchRequests(r) + + if p.ice_getConnection(): + # + # Batch request via connection + # + con = p.ice_getConnection() + p2 = p.ice_batchOneway() + p2.ice_ping() + r = con.begin_flushBatchRequests() + test(r.getConnection() == con) + test(r.getCommunicator() == communicator) + test(r.getProxy() == None) # Expected + con.end_flushBatchRequests(r) + + # + # Batch request via communicator + # + p2 = p.ice_batchOneway() + p2.ice_ping() + r = communicator.begin_flushBatchRequests() + test(r.getConnection() == None) # Expected + test(r.getCommunicator() == communicator) + test(r.getProxy() == None) # Expected + communicator.end_flushBatchRequests(r) + + if(p.ice_getConnection()): + r1 = None; + r2 = None; + + if sys.version_info[0] == 2: + b = [chr(random.randint(0, 255)) for x in range(0, 10024)] + seq = ''.join(b) + else: + b = [random.randint(0, 255) for x in range(0, 10024)] + seq = bytes(b) + + testController.holdAdapter() + + for x in range(0, 200): # 2MB + r = p.begin_opWithPayload(seq) + + test(not r.isSent()) + + r1 = p.begin_ice_ping() + r2 = p.begin_ice_id() + r1.cancel() + r2.cancel() + try: + p.end_ice_ping(r1) + test(false) + except(Ice.InvocationCanceledException): + pass + + try: + p.end_ice_id(r2) + test(false) + except(Ice.InvocationCanceledException): + pass + + testController.resumeAdapter() + p.ice_ping() + test(not r1.isSent() and r1.isCompleted()) + test(not r2.isSent() and r2.isCompleted()) + + testController.holdAdapter() + + r1 = p.begin_op() + r2 = p.begin_ice_id() + r1.waitForSent() + r2.waitForSent() + r1.cancel() + r2.cancel() + try: + p.end_op(r1) + test(false) + except: + pass + try: + p.end_ice_id(r2) + test(false) + except: + pass + testController.resumeAdapter() + + print("ok") + + if p.ice_getConnection(): + sys.stdout.write("testing close connection with sending queue... ") + sys.stdout.flush() + + if sys.version_info[0] == 2: + b = [chr(random.randint(0, 255)) for x in range(0, 10*1024)] + seq = ''.join(b) + else: + b = [random.randint(0, 255) for x in range(0, 10*1024)] + seq = bytes(b) + + # + # Send multiple opWithPayload, followed by a close and followed by multiple opWithPaylod. + # The goal is to make sure that none of the opWithPayload fail even if the server closes + # the connection gracefully in between. + # + maxQueue = 2 + done = False + while not done and maxQueue < 50: + done = True + p.ice_ping() + results = [] + for i in range(0, maxQueue): + results.append(p.begin_opWithPayload(seq)) + if not p.begin_close(False).isSent(): + for i in range(0, maxQueue): + r = p.begin_opWithPayload(seq) + results.append(r) + if r.isSent(): + done = False + maxQueue = maxQueue * 2 + break + else: + maxQueue = maxQueue * 2 + done = False + for r in results: + r.waitForCompleted() + try: + r.throwLocalException() + except Ice.LocalException: + test(False) + + print("ok") + + p.shutdown() diff --git a/python/test/Ice/ami/Client.py b/python/test/Ice/ami/Client.py new file mode 100755 index 00000000000..8eeb8ed7ea5 --- /dev/null +++ b/python/test/Ice/ami/Client.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + AllTests.allTests(communicator, False) + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty('Ice.Warn.AMICallback', '0') + + # + # Limit the send buffer size, this test relies on the socket + # send() blocking after sending a given amount of data. + # + initData.properties.setProperty("Ice.TCP.SndSize", "50000"); + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/ami/Collocated.py b/python/test/Ice/ami/Collocated.py new file mode 100755 index 00000000000..11a885f82f9 --- /dev/null +++ b/python/test/Ice/ami/Collocated.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + communicator.getProperties().setProperty("ControllerAdapter.Endpoints", "default -p 12011") + communicator.getProperties().setProperty("ControllerAdapter.ThreadPool.Size", "1") + + adapter = communicator.createObjectAdapter("TestAdapter") + adapter2 = communicator.createObjectAdapter("ControllerAdapter") + + testController = TestI.TestIntfControllerI(adapter) + + adapter.add(TestI.TestIntfI(), communicator.stringToIdentity("test")) + #adapter.activate() # Collocated test doesn't need to active the OA + + adapter2.add(testController, communicator.stringToIdentity("testController")) + #adapter2.activate() # Collocated test doesn't need to active the OA + + AllTests.allTests(communicator, True) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + + initData.properties.setProperty("Ice.Warn.AMICallback", "0"); + + # + # This test kills connections, so we don't want warnings. + # + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/ami/Server.py b/python/test/Ice/ami/Server.py new file mode 100755 index 00000000000..bae6f92fd7e --- /dev/null +++ b/python/test/Ice/ami/Server.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + communicator.getProperties().setProperty("ControllerAdapter.Endpoints", "default -p 12011") + communicator.getProperties().setProperty("ControllerAdapter.ThreadPool.Size", "1") + + adapter = communicator.createObjectAdapter("TestAdapter") + adapter2 = communicator.createObjectAdapter("ControllerAdapter") + + testController = TestI.TestIntfControllerI(adapter) + + adapter.add(TestI.TestIntfI(), communicator.stringToIdentity("test")) + adapter.activate() + + adapter2.add(testController, communicator.stringToIdentity("testController")) + adapter2.activate() + + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + + # + # This test kills connections, so we don't want warnings. + # + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + # + # Limit the recv buffer size, this test relies on the socket + # send() blocking after sending a given amount of data. + # + initData.properties.setProperty("Ice.TCP.RcvSize", "50000"); + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/ami/Test.ice b/python/test/Ice/ami/Test.ice new file mode 100644 index 00000000000..1bf95e7798f --- /dev/null +++ b/python/test/Ice/ami/Test.ice @@ -0,0 +1,45 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/BuiltinSequences.ice> +#include <Ice/Endpoint.ice> + +module Test +{ + +exception TestIntfException +{ +}; + +interface TestIntf +{ + void op(); + void opWithPayload(Ice::ByteSeq seq); + int opWithResult(); + void opWithUE() + throws TestIntfException; + void opBatch(); + int opBatchCount(); + bool waitForBatch(int count); + void close(bool force); + void shutdown(); + + bool supportsFunctionalTests(); +}; + +interface TestIntfController +{ + void holdAdapter(); + void resumeAdapter(); +}; + +}; + diff --git a/python/test/Ice/ami/TestI.py b/python/test/Ice/ami/TestI.py new file mode 100644 index 00000000000..c1f7642220a --- /dev/null +++ b/python/test/Ice/ami/TestI.py @@ -0,0 +1,72 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, threading + +class TestIntfI(Test.TestIntf): + def __init__(self): + self._cond = threading.Condition() + self._batchCount = 0 + + def op(self, current=None): + pass + + def opWithResult(self, current=None): + return 15 + + def opWithUE(self, current=None): + raise Test.TestIntfException() + + def opWithPayload(self, bytes, current=None): + pass + + def opBatch(self, current=None): + self._cond.acquire() + try: + self._batchCount += 1 + self._cond.notify() + finally: + self._cond.release() + + def opBatchCount(self, current=None): + self._cond.acquire() + try: + return self._batchCount + finally: + self._cond.release() + + def waitForBatch(self, count, current=None): + self._cond.acquire() + try: + while self._batchCount < count: + self._cond.wait(5) + result = count == self._batchCount + self._batchCount = 0 + return result + finally: + self._cond.release() + + def close(self, force, current=None): + current.con.close(force) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def supportsFunctionalTests(self, current=None): + return False + +class TestIntfControllerI(Test.TestIntfController): + def __init__(self, adapter): + self._adapter = adapter + + def holdAdapter(self, current=None): + self._adapter.hold() + + def resumeAdapter(self, current=None): + self._adapter.activate() diff --git a/python/test/Ice/ami/run.py b/python/test/Ice/ami/run.py new file mode 100755 index 00000000000..2307ecfe0a6 --- /dev/null +++ b/python/test/Ice/ami/run.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("tests with regular server.") +TestUtil.clientServerTest() +print("tests with collocated server.") +TestUtil.collocatedTest() diff --git a/python/test/Ice/application/Client.py b/python/test/Ice/application/Client.py new file mode 100755 index 00000000000..500c03395b0 --- /dev/null +++ b/python/test/Ice/application/Client.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, Ice, time + +class Client(Ice.Application): + def interruptCallback(self, sig): + print("handling signal " + str(sig)) + + # SIGINT interrupts time.sleep so a custom method is needed to + # sleep for a given interval. + def sleep(self, interval): + start = time.time() + while True: + sleepTime = (start + interval) - time.time() + if sleepTime <= 0: + break + time.sleep(sleepTime) + + def run(self, args): + self.ignoreInterrupt() + print("Ignore CTRL+C and the like for 5 seconds (try it!)") + self.sleep(5) + + self.callbackOnInterrupt() + + self.holdInterrupt() + print("Hold CTRL+C and the like for 5 seconds (try it!)") + self.sleep(5) + + self.releaseInterrupt() + print("Release CTRL+C (any held signals should be released)") + self.sleep(5) + + self.holdInterrupt() + print("Hold CTRL+C and the like for 5 seconds (try it!)") + self.sleep(5) + + self.callbackOnInterrupt() + print("Release CTRL+C (any held signals should be released)") + self.sleep(5) + + self.shutdownOnInterrupt() + print("Test shutdown on destroy. Press CTRL+C to shutdown & terminate") + self.communicator().waitForShutdown() + + print("ok") + return False + +app = Client() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/binding/AllTests.py b/python/test/Ice/binding/AllTests.py new file mode 100644 index 00000000000..c1ae07f7d91 --- /dev/null +++ b/python/test/Ice/binding/AllTests.py @@ -0,0 +1,651 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, random, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class GetAdapterNameCB: + def __init__(self): + self._name = "" + self._cond = threading.Condition() + + def response(self, name): + self._cond.acquire() + self._name = name + self._cond.notify() + self._cond.release() + + def exception(self, ex): + test(False) + + def getResult(self): + self._cond.acquire() + try: + while self._name == "": + self._cond.wait(5.0) + if self._name != "": + return self._name + else: + return "" + finally: + self._cond.release() + +def getAdapterNameWithAMI(proxy): + cb = GetAdapterNameCB() + proxy.begin_getAdapterName(cb.response, cb.exception) + return cb.getResult() + +def createTestIntfPrx(adapters): + endpoints = [] + test = None + for p in adapters: + test = p.getTestIntf() + edpts = test.ice_getEndpoints() + endpoints.extend(edpts) + return Test.TestIntfPrx.uncheckedCast(test.ice_endpoints(endpoints)) + +def deactivate(com, adapters): + for p in adapters: + com.deactivateObjectAdapter(p) + +def allTests(communicator): + ref = "communicator:default -p 12010" + com = Test.RemoteCommunicatorPrx.uncheckedCast(communicator.stringToProxy(ref)) + + sys.stdout.write("testing binding with single endpoint... ") + sys.stdout.flush() + + adapter = com.createObjectAdapter("Adapter", "default") + + test1 = adapter.getTestIntf() + test2 = adapter.getTestIntf() + test(test1.ice_getConnection() == test2.ice_getConnection()) + + test1.ice_ping() + test2.ice_ping() + + com.deactivateObjectAdapter(adapter) + + test3 = Test.TestIntfPrx.uncheckedCast(test1) + test(test3.ice_getConnection() == test1.ice_getConnection()) + test(test3.ice_getConnection() == test2.ice_getConnection()) + + try: + test3.ice_ping() + test(False) + except Ice.ConnectionRefusedException: + pass + + print("ok") + + sys.stdout.write("testing binding with multiple endpoints... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter11", "default")) + adapters.append(com.createObjectAdapter("Adapter12", "default")) + adapters.append(com.createObjectAdapter("Adapter13", "default")) + + # + # Ensure that when a connection is opened it's reused for new + # proxies and that all endpoints are eventually tried. + # + names = ["Adapter11", "Adapter12", "Adapter13"] + while len(names) > 0: + adpts = adapters[:] + + test1 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test2 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test3 = createTestIntfPrx(adpts) + + test(test1.ice_getConnection() == test2.ice_getConnection()) + test(test2.ice_getConnection() == test3.ice_getConnection()) + + name = test1.getAdapterName() + if names.count(name) > 0: + names.remove(name) + test1.ice_getConnection().close(False) + + # + # Ensure that the proxy correctly caches the connection (we + # always send the request over the same connection.) + # + for a in adapters: + a.getTestIntf().ice_ping() + + t = createTestIntfPrx(adapters) + name = t.getAdapterName() + i = 0 + nRetry = 5 + while i < nRetry and t.getAdapterName() == name: + i = i + 1 + test(i == nRetry) + + for a in adapters: + a.getTestIntf().ice_getConnection().close(False) + + # + # Deactivate an adapter and ensure that we can still + # establish the connection to the remaining adapters. + # + com.deactivateObjectAdapter(adapters[0]) + names.append("Adapter12") + names.append("Adapter13") + while len(names) > 0: + adpts = adapters[:] + + test1 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test2 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test3 = createTestIntfPrx(adpts) + + test(test1.ice_getConnection() == test2.ice_getConnection()) + test(test2.ice_getConnection() == test3.ice_getConnection()) + + name = test1.getAdapterName() + if names.count(name) > 0: + names.remove(name) + test1.ice_getConnection().close(False) + + # + # Deactivate an adapter and ensure that we can still + # establish the connection to the remaining adapters. + # + com.deactivateObjectAdapter(adapters[2]) + t = createTestIntfPrx(adapters) + test(t.getAdapterName() == "Adapter12") + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing binding with multiple endpoints and AMI... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("AdapterAMI11", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI12", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI13", "default")) + + # + # Ensure that when a connection is opened it's reused for new + # proxies and that all endpoints are eventually tried. + # + names = ["AdapterAMI11", "AdapterAMI12", "AdapterAMI13"] + while len(names) > 0: + adpts = adapters[:] + + test1 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test2 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test3 = createTestIntfPrx(adpts) + + test(test1.ice_getConnection() == test2.ice_getConnection()) + test(test2.ice_getConnection() == test3.ice_getConnection()) + + name = getAdapterNameWithAMI(test1) + if names.count(name) > 0: + names.remove(name) + test1.ice_getConnection().close(False) + + # + # Ensure that the proxy correctly caches the connection (we + # always send the request over the same connection.) + # + for a in adapters: + a.getTestIntf().ice_ping() + + t = createTestIntfPrx(adapters) + name = getAdapterNameWithAMI(t) + i = 0 + nRetry = 5 + while i < nRetry and getAdapterNameWithAMI(t) == name: + i = i + 1 + test(i == nRetry) + + for a in adapters: + a.getTestIntf().ice_getConnection().close(False) + + # + # Deactivate an adapter and ensure that we can still + # establish the connection to the remaining adapters. + # + com.deactivateObjectAdapter(adapters[0]) + names.append("AdapterAMI12") + names.append("AdapterAMI13") + while len(names) > 0: + adpts = adapters[:] + + test1 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test2 = createTestIntfPrx(adpts) + random.shuffle(adpts) + test3 = createTestIntfPrx(adpts) + + test(test1.ice_getConnection() == test2.ice_getConnection()) + test(test2.ice_getConnection() == test3.ice_getConnection()) + + name = getAdapterNameWithAMI(test1) + if names.count(name) > 0: + names.remove(name) + test1.ice_getConnection().close(False) + + # + # Deactivate an adapter and ensure that we can still + # establish the connection to the remaining adapters. + # + com.deactivateObjectAdapter(adapters[2]) + t = createTestIntfPrx(adapters) + test(getAdapterNameWithAMI(t) == "AdapterAMI12") + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing random endpoint selection... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter21", "default")) + adapters.append(com.createObjectAdapter("Adapter22", "default")) + adapters.append(com.createObjectAdapter("Adapter23", "default")) + + t = createTestIntfPrx(adapters) + test(t.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random) + + names = ["Adapter21", "Adapter22", "Adapter23"] + while len(names) > 0: + name = t.getAdapterName() + if names.count(name) > 0: + names.remove(name) + t.ice_getConnection().close(False) + + t = Test.TestIntfPrx.uncheckedCast(t.ice_endpointSelection(Ice.EndpointSelectionType.Random)) + test(t.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random) + + names.append("Adapter21") + names.append("Adapter22") + names.append("Adapter23") + while len(names) > 0: + name = t.getAdapterName() + if names.count(name) > 0: + names.remove(name) + t.ice_getConnection().close(False) + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing ordered endpoint selection... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter31", "default")) + adapters.append(com.createObjectAdapter("Adapter32", "default")) + adapters.append(com.createObjectAdapter("Adapter33", "default")) + + t = createTestIntfPrx(adapters) + t = Test.TestIntfPrx.uncheckedCast(t.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)) + test(t.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered) + nRetry = 5 + + # + # Ensure that endpoints are tried in order by deactivating the adapters + # one after the other. + # + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter31": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[0]) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter32": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[1]) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter33": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[2]) + + try: + t.getAdapterName() + except Ice.ConnectionRefusedException: + pass + + endpoints = t.ice_getEndpoints() + + adapters = [] + + # + # Now, re-activate the adapters with the same endpoints in the opposite + # order. + # + adapters.append(com.createObjectAdapter("Adapter36", endpoints[2].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter36": + i = i + 1 + test(i == nRetry) + t.ice_getConnection().close(False) + adapters.append(com.createObjectAdapter("Adapter35", endpoints[1].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter35": + i = i + 1 + test(i == nRetry) + t.ice_getConnection().close(False) + adapters.append(com.createObjectAdapter("Adapter34", endpoints[0].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter34": + i = i + 1 + test(i == nRetry) + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing per request binding with single endpoint... ") + sys.stdout.flush() + + adapter = com.createObjectAdapter("Adapter41", "default") + + test1 = Test.TestIntfPrx.uncheckedCast(adapter.getTestIntf().ice_connectionCached(False)) + test2 = Test.TestIntfPrx.uncheckedCast(adapter.getTestIntf().ice_connectionCached(False)) + test(not test1.ice_isConnectionCached()) + test(not test2.ice_isConnectionCached()) + test(test1.ice_getConnection() == test2.ice_getConnection()) + + test1.ice_ping() + + com.deactivateObjectAdapter(adapter) + + test3 = Test.TestIntfPrx.uncheckedCast(test1) + try: + test(test3.ice_getConnection() == test1.ice_getConnection()) + test(False) + except Ice.ConnectionRefusedException: + pass + + print("ok") + + sys.stdout.write("testing per request binding with multiple endpoints... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter51", "default")) + adapters.append(com.createObjectAdapter("Adapter52", "default")) + adapters.append(com.createObjectAdapter("Adapter53", "default")) + + t = Test.TestIntfPrx.uncheckedCast(createTestIntfPrx(adapters).ice_connectionCached(False)) + test(not t.ice_isConnectionCached()) + + names = ["Adapter51", "Adapter52", "Adapter53"] + while len(names) > 0: + name = t.getAdapterName() + if names.count(name) > 0: + names.remove(name) + + com.deactivateObjectAdapter(adapters[0]) + + names.append("Adapter52") + names.append("Adapter53") + while len(names) > 0: + name = t.getAdapterName() + if names.count(name) > 0: + names.remove(name) + + com.deactivateObjectAdapter(adapters[2]) + + test(t.getAdapterName() == "Adapter52") + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing per request binding with multiple endpoints and AMI... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("AdapterAMI51", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI52", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI53", "default")) + + t = Test.TestIntfPrx.uncheckedCast(createTestIntfPrx(adapters).ice_connectionCached(False)) + test(not t.ice_isConnectionCached()) + + names = ["AdapterAMI51", "AdapterAMI52", "AdapterAMI53"] + while len(names) > 0: + name = getAdapterNameWithAMI(t) + if names.count(name) > 0: + names.remove(name) + + com.deactivateObjectAdapter(adapters[0]) + + names.append("AdapterAMI52") + names.append("AdapterAMI53") + while len(names) > 0: + name = getAdapterNameWithAMI(t) + if names.count(name) > 0: + names.remove(name) + + com.deactivateObjectAdapter(adapters[2]) + + test(getAdapterNameWithAMI(t) == "AdapterAMI52") + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing per request binding and ordered endpoint selection... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter61", "default")) + adapters.append(com.createObjectAdapter("Adapter62", "default")) + adapters.append(com.createObjectAdapter("Adapter63", "default")) + + t = createTestIntfPrx(adapters) + t = Test.TestIntfPrx.uncheckedCast(t.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)) + test(t.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered) + t = Test.TestIntfPrx.uncheckedCast(t.ice_connectionCached(False)) + test(not t.ice_isConnectionCached()) + nRetry = 5 + + # + # Ensure that endpoints are tried in order by deactiving the adapters + # one after the other. + # + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter61": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[0]) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter62": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[1]) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter63": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[2]) + + try: + t.getAdapterName() + except Ice.ConnectionRefusedException: + pass + + endpoints = t.ice_getEndpoints() + + adapters = [] + + # + # Now, re-activate the adapters with the same endpoints in the opposite + # order. + # + adapters.append(com.createObjectAdapter("Adapter66", endpoints[2].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter66": + i = i + 1 + test(i == nRetry) + adapters.append(com.createObjectAdapter("Adapter65", endpoints[1].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter65": + i = i + 1 + test(i == nRetry) + adapters.append(com.createObjectAdapter("Adapter64", endpoints[0].toString())) + i = 0 + while i < nRetry and t.getAdapterName() == "Adapter64": + i = i + 1 + test(i == nRetry) + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing per request binding and ordered endpoint selection and AMI... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("AdapterAMI61", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI62", "default")) + adapters.append(com.createObjectAdapter("AdapterAMI63", "default")) + + t = createTestIntfPrx(adapters) + t = Test.TestIntfPrx.uncheckedCast(t.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)) + test(t.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered) + t = Test.TestIntfPrx.uncheckedCast(t.ice_connectionCached(False)) + test(not t.ice_isConnectionCached()) + nRetry = 5 + + # + # Ensure that endpoints are tried in order by deactiving the adapters + # one after the other. + # + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI61": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[0]) + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI62": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[1]) + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI63": + i = i + 1 + test(i == nRetry) + com.deactivateObjectAdapter(adapters[2]) + + try: + t.getAdapterName() + except Ice.ConnectionRefusedException: + pass + + endpoints = t.ice_getEndpoints() + + adapters = [] + + # + # Now, re-activate the adapters with the same endpoints in the opposite + # order. + # + adapters.append(com.createObjectAdapter("AdapterAMI66", endpoints[2].toString())) + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI66": + i = i + 1 + test(i == nRetry) + adapters.append(com.createObjectAdapter("AdapterAMI65", endpoints[1].toString())) + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI65": + i = i + 1 + test(i == nRetry) + adapters.append(com.createObjectAdapter("AdapterAMI64", endpoints[0].toString())) + i = 0 + while i < nRetry and getAdapterNameWithAMI(t) == "AdapterAMI64": + i = i + 1 + test(i == nRetry) + + deactivate(com, adapters) + + print("ok") + + sys.stdout.write("testing endpoint mode filtering... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter71", "default")) + adapters.append(com.createObjectAdapter("Adapter72", "udp")) + + t = createTestIntfPrx(adapters) + test(t.getAdapterName() == "Adapter71") + + testUDP = Test.TestIntfPrx.uncheckedCast(t.ice_datagram()) + test(t.ice_getConnection() != testUDP.ice_getConnection()) + try: + testUDP.getAdapterName() + except Ice.TwowayOnlyException: + pass + + print("ok") + + if(len(communicator.getProperties().getProperty("Ice.Plugin.IceSSL")) > 0): + sys.stdout.write("testing unsecure vs. secure endpoints... ") + sys.stdout.flush() + + adapters = [] + adapters.append(com.createObjectAdapter("Adapter81", "ssl")) + adapters.append(com.createObjectAdapter("Adapter82", "tcp")) + + t = createTestIntfPrx(adapters) + for i in range(0, 5): + test(t.getAdapterName() == "Adapter82") + t.ice_getConnection().close(False) + + testSecure = Test.TestIntfPrx.uncheckedCast(t.ice_secure(True)) + test(testSecure.ice_isSecure()) + testSecure = Test.TestIntfPrx.uncheckedCast(t.ice_secure(False)) + test(not testSecure.ice_isSecure()) + testSecure = Test.TestIntfPrx.uncheckedCast(t.ice_secure(True)) + test(testSecure.ice_isSecure()) + test(t.ice_getConnection() != testSecure.ice_getConnection()) + + com.deactivateObjectAdapter(adapters[1]) + + for i in range(0, 5): + test(t.getAdapterName() == "Adapter81") + t.ice_getConnection().close(False) + + com.createObjectAdapter("Adapter83", (t.ice_getEndpoints()[1]).toString()) # Reactive tcp OA. + + for i in range(0, 5): + test(t.getAdapterName() == "Adapter83") + t.ice_getConnection().close(False) + + com.deactivateObjectAdapter(adapters[0]) + try: + testSecure.ice_ping() + test(False) + except Ice.ConnectionRefusedException: + pass + + deactivate(com, adapters) + + print("ok") + + com.shutdown() diff --git a/python/test/Ice/binding/Client.py b/python/test/Ice/binding/Client.py new file mode 100755 index 00000000000..7cc8180a8fc --- /dev/null +++ b/python/test/Ice/binding/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import AllTests + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/binding/Server.py b/python/test/Ice/binding/Server.py new file mode 100755 index 00000000000..25d7602fcb4 --- /dev/null +++ b/python/test/Ice/binding/Server.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + id = communicator.stringToIdentity("communicator") + adapter.add(TestI.RemoteCommunicatorI(), id) + adapter.activate() + + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/binding/Test.ice b/python/test/Ice/binding/Test.ice new file mode 100644 index 00000000000..bd7cbe1a971 --- /dev/null +++ b/python/test/Ice/binding/Test.ice @@ -0,0 +1,36 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + string getAdapterName(); +}; + +interface RemoteObjectAdapter +{ + TestIntf* getTestIntf(); + + void deactivate(); +}; + +interface RemoteCommunicator +{ + RemoteObjectAdapter* createObjectAdapter(string name, string endpoints); + + void deactivateObjectAdapter(RemoteObjectAdapter* adapter); + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/binding/TestI.py b/python/test/Ice/binding/TestI.py new file mode 100644 index 00000000000..c24cf074c4b --- /dev/null +++ b/python/test/Ice/binding/TestI.py @@ -0,0 +1,42 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test + +class RemoteCommunicatorI(Test.RemoteCommunicator): + def createObjectAdapter(self, name, endpoints, current=None): + com = current.adapter.getCommunicator() + com.getProperties().setProperty(name + ".ThreadPool.Size", "1") + adapter = com.createObjectAdapterWithEndpoints(name, endpoints) + return Test.RemoteObjectAdapterPrx.uncheckedCast(current.adapter.addWithUUID(RemoteObjectAdapterI(adapter))) + + def deactivateObjectAdapter(self, adapter, current=None): + adapter.deactivate() + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +class RemoteObjectAdapterI(Test.RemoteObjectAdapter): + def __init__(self, adapter): + self._adapter = adapter + self._testIntf = Test.TestIntfPrx.uncheckedCast(self._adapter.add(TestI(), adapter.getCommunicator().stringToIdentity("test"))) + self._adapter.activate() + + def getTestIntf(self, current=None): + return self._testIntf + + def deactivate(self, current=None): + try: + self._adapter.destroy() + except Ice.ObjectAdapterDeactivatedException: + pass + +class TestI(Test.TestIntf): + def getAdapterName(self, current=None): + return current.adapter.getName() diff --git a/python/test/Ice/binding/run.py b/python/test/Ice/binding/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/binding/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/blobject/Client.py b/python/test/Ice/blobject/Client.py new file mode 100755 index 00000000000..8fb5d04c61e --- /dev/null +++ b/python/test/Ice/blobject/Client.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test +import RouterI + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator, sync): + hello = Test.HelloPrx.checkedCast(communicator.stringToProxy("test:default -p 12010")) + hello.sayHello(False) + hello.sayHello(False, { "_fwd":"o" } ) + test(hello.add(10, 20) == 30) + try: + hello.raiseUE() + test(False) + except Test.UE: + pass + + try: + Test.HelloPrx.checkedCast(communicator.stringToProxy("unknown:default -p 12010 -t 10000")) + test(False) + except Ice.ObjectNotExistException: + pass + + # First try an object at a non-existent endpoint. + try: + Test.HelloPrx.checkedCast(communicator.stringToProxy("missing:default -p 12000 -t 10000")) + test(False) + except Ice.UnknownLocalException as e: + test(e.unknown.find('ConnectionRefusedException')) + if sync: + hello.shutdown() + return True + +argv = sys.argv[:] # Clone the arguments to use again later + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(argv) + initData.properties.setProperty('Ice.Warn.Dispatch', '0') + communicator = Ice.initialize(argv, initData) + router = RouterI.RouterI(communicator, False) + sys.stdout.write("testing async blobject... ") + sys.stdout.flush() + status = run(sys.argv, communicator, False) + print("ok") + router.destroy() +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +if status: + try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty('Ice.Warn.Dispatch', '0') + communicator = Ice.initialize(sys.argv, initData) + router = RouterI.RouterI(communicator, True) + sys.stdout.write("testing sync blobject... ") + sys.stdout.flush() + status = run(sys.argv, communicator, True) + print("ok") + router.destroy() + except: + traceback.print_exc() + status = False + + if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/blobject/RouterI.py b/python/test/Ice/blobject/RouterI.py new file mode 100644 index 00000000000..47582a06b33 --- /dev/null +++ b/python/test/Ice/blobject/RouterI.py @@ -0,0 +1,172 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import threading, Ice + +class CallQueue(threading.Thread): + def __init__(self): + threading.Thread.__init__(self) + self._condVar = threading.Condition() + self._queue = [] + self._destroy = False + + def add(self, call): + self._condVar.acquire() + self._queue.append(call) + self._condVar.notify() + self._condVar.release() + + def destroy(self): + self._condVar.acquire() + self._destroy = True + self._condVar.notify() + self._condVar.release() + + def run(self): + while True: + self._condVar.acquire() + while len(self._queue) == 0 and not self._destroy: + self._condVar.wait() + if self._destroy: + self._condVar.release() + break + call = self._queue.pop() + self._condVar.release() + call.execute() + +class AsyncCallback(object): + def __init__(self, cb): + self._cb = cb + + def response(self, ok, results): + self._cb.ice_response(ok, results) + + def exception(self, ex): + self._cb.ice_exception(ex) + +class BlobjectCall(object): + def __init__(self, proxy, amdCallback, inParams, curr): + self._proxy = proxy + self._amdCallback = amdCallback + self._inParams = inParams + self._curr = curr + + def execute(self): + proxy = self._proxy + if len(self._curr.facet) > 0: + proxy = self._proxy.ice_facet(self._curr.facet) + + if "_fwd" in self._curr.ctx and self._curr.ctx["_fwd"] == "o": + proxy = proxy.ice_oneway() + try: + ok, out = proxy.ice_invoke(self._curr.operation, self._curr.mode, self._inParams, self._curr.ctx) + self._amdCallback.ice_response(ok, out) + except Ice.Exception as e: + self._amdCallback.ice_exception(e) + else: + cb = AsyncCallback(self._amdCallback) + proxy.begin_ice_invoke(self._curr.operation, self._curr.mode, self._inParams, cb.response, cb.exception, + None, self._curr.ctx) + +class BlobjectAsyncI(Ice.BlobjectAsync): + def __init__(self): + self._queue = CallQueue() + self._queue.start() + self._objects = {} + self._lock = threading.Lock() + + def ice_invoke_async(self, amdCallback, inParams, curr): + self._lock.acquire() + proxy = self._objects[curr.id] + assert proxy + self._lock.release() + self._queue.add(BlobjectCall(proxy, amdCallback, inParams, curr)) + + def add(self, proxy): + self._lock.acquire() + self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None) + self._lock.release() + + def destroy(self): + self._lock.acquire() + self._queue.destroy() + self._queue.join() + self._lock.release() + +class BlobjectI(Ice.Blobject): + def __init__(self): + self._objects = {} + self._lock = threading.Lock() + + def ice_invoke(self, inParams, curr): + self._lock.acquire() + proxy = self._objects[curr.id] + self._lock.release() + + if len(curr.facet) > 0: + proxy = proxy.ice_facet(curr.facet) + + try: + if "_fwd" in curr.ctx and curr.ctx["_fwd"] == "o": + proxy = proxy.ice_oneway() + return proxy.ice_invoke(curr.operation, curr.mode, inParams, curr.ctx) + else: + return proxy.ice_invoke(curr.operation, curr.mode, inParams, curr.ctx) + except Ice.Exception as e: + raise + + def add(self, proxy): + self._lock.acquire() + self._objects[proxy.ice_getIdentity()] = proxy.ice_facet("").ice_twoway().ice_router(None) + self._lock.release() + + def destroy(self): + pass + +class ServantLocatorI(Ice.ServantLocator): + def __init__(self, blobject): + self._blobject = blobject + + def locate(self, current): + return self._blobject # and the cookie + + def finished(self, current, object, cookie): + pass + + def deactivate(self, s): + pass + +class RouterI(Ice.Router): + def __init__(self, communicator, sync): + self._adapter = communicator.createObjectAdapterWithEndpoints("forward", "default -h 127.0.0.1") + if sync: + self._blobject = BlobjectI() + else: + self._blobject = BlobjectAsyncI() + self._adapter.addServantLocator(ServantLocatorI(self._blobject), "") + self._blobjectProxy = self._adapter.addWithUUID(self._blobject) + proxy = Ice.RouterPrx.uncheckedCast(self._adapter.addWithUUID(self)) + communicator.setDefaultRouter(proxy) + self._adapter.activate() + + def useSync(self, sync): + self._locator.useSync(sync) + + def getClientProxy(self, current): + return self._blobjectProxy + + def getServerProxy(self, current): + assert false + + def addProxies(self, proxies, current): + for p in proxies: + self._blobject.add(p) + + def destroy(self): + self._blobject.destroy() diff --git a/python/test/Ice/blobject/Server.py b/python/test/Ice/blobject/Server.py new file mode 100755 index 00000000000..0dbd92a4b68 --- /dev/null +++ b/python/test/Ice/blobject/Server.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import Test + +class TestI(Test.Hello): + def sayHello(self, delay, current=None): + if delay != 0: + time.sleep(delay / 1000.0) + + def raiseUE(self, current=None): + raise Test.UE() + + def add(self, s1, s2, current=None): + return s1 + s2 + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TestI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + # + # Its possible to have batch oneway requests dispatched after the + # adapter is deactivated due to thread scheduling so we supress + # this warning. + # + initData.properties.setProperty("Ice.Warn.Dispatch", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/blobject/Test.ice b/python/test/Ice/blobject/Test.ice new file mode 100644 index 00000000000..967825ffbf7 --- /dev/null +++ b/python/test/Ice/blobject/Test.ice @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception UE +{ +}; + +interface Hello +{ + void sayHello(int delay); + int add(int s1, int s2); + void raiseUE() + throws UE; + void shutdown(); +}; + +}; diff --git a/python/test/Ice/blobject/run.py b/python/test/Ice/blobject/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/blobject/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/checksum/AllTests.py b/python/test/Ice/checksum/AllTests.py new file mode 100644 index 00000000000..cece6a1d908 --- /dev/null +++ b/python/test/Ice/checksum/AllTests.py @@ -0,0 +1,59 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, string, re, traceback, Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + ref = "test:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + + checksum = Test.ChecksumPrx.checkedCast(base) + test(checksum) + + # + # Verify that no checksums are present for local types. + # + sys.stdout.write("testing checksums... ") + sys.stdout.flush() + test(len(Ice.sliceChecksums) > 0) + for i in Ice.sliceChecksums: + test(i.find("Local") == -1) + + # + # Get server's Slice checksums. + # + d = checksum.getSliceChecksums() + + # + # Compare the checksums. For a type FooN whose name ends in an integer N, + # we assume that the server's type does not change for N = 1, and does + # change for N > 1. + # + patt = re.compile("\\d+") + for i in d: + n = 0 + m = patt.search(i) + if m: + n = int(i[m.start():]) + + test(i in Ice.sliceChecksums) + + if n <= 1: + test(Ice.sliceChecksums[i] == d[i]) + else: + test(Ice.sliceChecksums[i] != d[i]) + + print("ok") + + return checksum diff --git a/python/test/Ice/checksum/CTypes.ice b/python/test/Ice/checksum/CTypes.ice new file mode 100644 index 00000000000..1dfc5f719d5 --- /dev/null +++ b/python/test/Ice/checksum/CTypes.ice @@ -0,0 +1,634 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +// +// TEST: Same +// +const int IntConst1 = 100; + +// +// TEST: Value changed +// +const int IntConst2 = 100; + +// +// TEST: Type changed +// +const int IntConst3 = 100; + +// +// TEST: Same +// +enum Enum1 { Enum11, Enum12, Enum13 }; + +// +// TEST: Add enumerator +// +enum Enum2 { Enum21, Enum22, Enum23 }; + +// +// TEST: Remove enumerator +// +enum Enum3 { Enum31, Enum32, Enum33 }; + +// +// TEST: Change to a different type +// +enum Enum4 { Enum41, Enum42, Enum43 }; + +// +// TEST: Enum with explicit values. +// +enum EnumExplicit0 { EnumExplicit01 = 1, EnumExplicit02 = 2, EnumExplicit03 = 3 }; + +// +// TEST: Enum with same explicit values, different order. +// +enum EnumExplicit1 { EnumExplicit11 = 1, EnumExplicit12 = 2, EnumExplicit13 = 3 }; + +// +// TEST: Enum with different explicit values. +// +enum EnumExplicit2 { EnumExplicit21 = 1, EnumExplicit22 = 2, EnumExplicit23 = 3}; + +// +// TEST: Enum with explicit values, removed enumerator. +// +enum EnumExplicit3 { EnumExplicit31 = 1, EnumExplicit32 = 2, EnumExplicit33 = 3}; + +// +// TEST: Same +// +sequence<int> Sequence1; + +// +// TEST: Change sequence type +// +sequence<int> Sequence2; + +// +// TEST: Change to a different type +// +sequence<int> Sequence3; + +// +// TEST: Same +// +dictionary<string, int> Dictionary1; + +// +// TEST: Change key type +// +dictionary<string, int> Dictionary2; + +// +// TEST: Change value type +// +dictionary<string, int> Dictionary3; + +// +// TEST: Change to a different type +// +dictionary<string, int> Dictionary4; + +// +// TEST: Same +// +struct Struct1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +struct Struct2 +{ + string str; + bool b; +}; + +// +// TEST: Change member type +// +struct Struct3 +{ + string str; + bool b; +}; + +// +// TEST: Remove member +// +struct Struct4 +{ + string str; + bool b; +}; + +// +// TEST: Change to a different type +// +struct Struct5 +{ + string str; + bool b; +}; + +// +// TEST: Same +// +interface Interface1 +{ +}; + +// +// TEST: Change interface to class +// +interface Interface2 +{ +}; + +// +// TEST: Add base interface +// +interface Interface3 +{ +}; + +// +// TEST: Add operation +// +interface Interface4 +{ +}; + +// +// TEST: Same +// +class EmptyClass1 +{ +}; + +// +// TEST: Add data member +// +class EmptyClass2 +{ +}; + +// +// TEST: Add operation +// +class EmptyClass3 +{ +}; + +// +// TEST: Add base class +// +class EmptyClass4 +{ +}; + +// +// TEST: Add interface +// +class EmptyClass5 +{ +}; + +// +// TEST: Same +// +class SimpleClass1 +{ + string str; + float f; +}; + +// +// TEST: Add operation +// +class SimpleClass2 +{ + string str; + float f; +}; + +// +// TEST: Rename member +// +class SimpleClass3 +{ + string str; + float f; +}; + +// +// TEST: Add member +// +class SimpleClass4 +{ + string str; + float f; +}; + +// +// TEST: Remove member +// +class SimpleClass5 +{ + string str; + float f; +}; + +// +// TEST: Reorder members +// +class SimpleClass6 +{ + string str; + float f; +}; + +// +// TEST: Change member type +// +class SimpleClass7 +{ + string str; + float f; +}; + +// +// TEST: Same +// +exception Exception1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +exception Exception2 +{ + string str; + bool b; +}; + +// +// TEST: Change member type +// +exception Exception3 +{ + string str; + bool b; +}; + +// +// TEST: Remove member +// +exception Exception4 +{ + string str; + bool b; +}; + +// +// TEST: Add base exception +// +exception Exception5 +{ +}; + +// +// TEST: Change to a different type +// +exception Exception6 +{ + string str; + bool b; +}; + +// +// TEST: Exception with optional members. +// +exception OptionalEx0 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Exception with optional members, different order, same tags. +// +exception OptionalEx1 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Exception with different optional members. +// +exception OptionalEx2 +{ + string firstName; + string secondName; + optional(1) string emailAddress; +}; + +// +// TEST: Exception with different optional members. +// +exception OptionalEx3 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Exception with optional members using different tags. +// +exception OptionalEx4 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Same +// +class BaseClass1 +{ + void baseOp1(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Change return type +// +class BaseClass2 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add parameter +// +class BaseClass3 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add exception +// +class BaseClass4 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Change out parameter to in parameter +// +class BaseClass5 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove parameter +// +class BaseClass6 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove exception +// +class BaseClass7 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Remove operation +// +class BaseClass8 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class +// +class BaseClass9 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add interface +// +class BaseClass10 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class and interface +// +class BaseClass11 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Class with compact id +// +class Compact1(1) +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Derived from class with compact id +// +class Derived1 extends Compact1 +{ +}; + +// +// TEST: Same class names but different compact id +// +class Compact2(2) +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Class with optional members. +// +class Optional0 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Class with optional members, different order, same tags. +// +class Optional1 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Class with different optional members. +// +class Optional2 +{ + string firstName; + string secondName; + optional(1) string emailAddress; +}; + +// +// TEST: Class with different optional members. +// +class Optional3 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Class with optional members using different tags. +// +class Optional4 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Class with optional parameters. +// +class OptionalParameters0 +{ + void op1(string firstName, optional(1) string secondName, + optional(2) string emailAddress); +}; + +// +// TEST: Class with optional parameters, different order. +// +class OptionalParameters1 +{ + void op1(string firstName, optional(1) string secondName, + optional(2) string emailAddress); +}; + +// +// TEST: Class with optional parameters, different tags. +// +class OptionalParameters2 +{ + void op1(string firstName, optional(1) string emailAddress, + optional(2) string secondName); +}; + +// +// TEST: Class with different optional parameters. +// +class OptionalParameters3 +{ + void op1(string firstName, optional(1) string emailAddress, + string secondName); +}; + +// +// TEST: Class with optional return type. +// +class OptionalReturn0 +{ + optional(1) int op(); +}; + +// +// TEST: Class that changes optional return type. +// +class OptionalReturn2 +{ + optional(1) int op(); +}; + +// +// TEST: Local +// +local enum LocalEnum { LocalEnum1, LocalEnum2, LocalEnum3 }; + +// +// TEST: Local +// +local sequence<string> LocalSequence; + +// +// TEST: Local +// +local dictionary<string, string> LocalDictionary; + +// +// TEST: Local +// +local struct LocalStruct +{ + string str; +}; + +// +// TEST: Local +// +local class LocalClass +{ +}; + +}; diff --git a/python/test/Ice/checksum/Client.py b/python/test/Ice/checksum/Client.py new file mode 100755 index 00000000000..592c84c632a --- /dev/null +++ b/python/test/Ice/checksum/Client.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' --checksum Test.ice CTypes.ice") +import Test, AllTests + +def run(args, communicator): + checksum = AllTests.allTests(communicator) + checksum.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/checksum/STypes.ice b/python/test/Ice/checksum/STypes.ice new file mode 100644 index 00000000000..00e0b76c2ea --- /dev/null +++ b/python/test/Ice/checksum/STypes.ice @@ -0,0 +1,631 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +// +// TEST: Same +// +const int IntConst1 = 100; + +// +// TEST: Value changed +// +const int IntConst2 = 1000; + +// +// TEST: Type changed +// +const short IntConst3 = 100; + +// +// TEST: Same +// +enum Enum1 { Enum11, Enum12, Enum13 }; + +// +// TEST: Add enumerator +// +enum Enum2 { Enum21, Enum22, Enum23, Enum24 }; + +// +// TEST: Remove enumerator +// +enum Enum3 { Enum32, Enum33 }; + +// +// TEST: Enum with explicit values. +// +enum EnumExplicit0 { EnumExplicit01 = 1, EnumExplicit02 = 2, EnumExplicit03 = 3 }; + +// +// TEST: Enum with same explicit values, different order. +// +enum EnumExplicit1 { EnumExplicit11 = 1, EnumExplicit13 = 3, EnumExplicit12 = 2 }; + +// +// TEST: Enum with different explicit values. +// +enum EnumExplicit2 { EnumExplicit21 = 1, EnumExplicit22 = 3, EnumExplicit23 }; + +// +// TEST: Enum with explicit values, removed enumerator. +// +enum EnumExplicit3 { EnumExplicit31 = 1, EnumExplicit32 = 2}; + +// +// TEST: Change to a different type +// +class Enum4 {}; + +// +// TEST: Same +// +sequence<int> Sequence1; + +// +// TEST: Change sequence type +// +sequence<short> Sequence2; + +// +// TEST: Change to a different type +// +class Sequence3 {}; + +// +// TEST: Same +// +dictionary<string, int> Dictionary1; + +// +// TEST: Change key type +// +dictionary<long, int> Dictionary2; + +// +// TEST: Change value type +// +dictionary<string, bool> Dictionary3; + +// +// TEST: Change to a different type +// +class Dictionary4 {}; + +// +// TEST: Same +// +struct Struct1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +struct Struct2 +{ + string str; + bool b; + float f; +}; + +// +// TEST: Change member type +// +struct Struct3 +{ + string str; + double b; +}; + +// +// TEST: Remove member +// +struct Struct4 +{ + bool b; +}; + +// +// TEST: Change to a different type +// +class Struct5 {}; + +// +// TEST: Same +// +interface Interface1 +{ +}; + +// +// TEST: Change interface to class +// +class Interface2 +{ +}; + +// +// TEST: Add base interface +// +interface Interface3 extends Interface1 +{ +}; + +// +// TEST: Add operation +// +interface Interface4 +{ + void opInterface4(); +}; + +// +// TEST: Same +// +class EmptyClass1 +{ +}; + +// +// TEST: Add data member +// +class EmptyClass2 +{ + double d; +}; + +// +// TEST: Add operation +// +class EmptyClass3 +{ + void newOp(); +}; + +// +// TEST: Add base class +// +class EmptyClass4 extends EmptyClass1 +{ +}; + +// +// TEST: Add interface +// +class EmptyClass5 implements Interface1 +{ +}; + +// +// TEST: Same +// +class SimpleClass1 +{ + string str; + float f; +}; + +// +// TEST: Add operation +// +class SimpleClass2 +{ + string str; + float f; + void newOp(); +}; + +// +// TEST: Rename member +// +class SimpleClass3 +{ + string str; + float g; +}; + +// +// TEST: Add member +// +class SimpleClass4 +{ + string str; + float f; + bool b; +}; + +// +// TEST: Remove member +// +class SimpleClass5 +{ + string str; +}; + +// +// TEST: Reorder members +// +class SimpleClass6 +{ + float f; + string str; +}; + +// +// TEST: Change member type +// +class SimpleClass7 +{ + string str; + double f; +}; + +// +// TEST: Same +// +exception Exception1 +{ + string str; + bool b; +}; + +// +// TEST: Add member +// +exception Exception2 +{ + string str; + bool b; + float f; +}; + +// +// TEST: Change member type +// +exception Exception3 +{ + string str; + double b; +}; + +// +// TEST: Remove member +// +exception Exception4 +{ + bool b; +}; + +// +// TEST: Add base exception +// +exception Exception5 extends Exception1 +{ +}; + +// +// TEST: Change to a different type +// +class Exception6 {}; + +// +// TEST: Exception with optional members. +// +exception OptionalEx0 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Exception with optional members, different order, same tags. +// +exception OptionalEx1 +{ + string firstName; + optional(2) string emailAddress; + optional(1) string secondName; +}; + +// +// TEST: Exception with different optional members. +// +exception OptionalEx2 +{ + string firstName; + optional(1) string secondName; + string emailAddress; +}; + +// +// TEST: Exception with different optional members. +// +exception OptionalEx3 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; + optional(3) string phoneNumber; +}; + +// +// TEST: Exception with optional members using different tags. +// +exception OptionalEx4 +{ + string firstName; + optional(2) string secondName; + optional(1) string emailAddress; +}; + +// +// TEST: Same +// +class BaseClass1 +{ + void baseOp1(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Change return type +// +class BaseClass2 +{ + int baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add parameter +// +class BaseClass3 +{ + void baseOp(Object o); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add exception +// +class BaseClass4 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1, Exception2; +}; + +// +// TEST: Change out parameter to in parameter +// +class BaseClass5 +{ + void baseOp(); + void baseOp2(int i, string s) throws Exception1; +}; + +// +// TEST: Remove parameter +// +class BaseClass6 +{ + void baseOp(); + void baseOp2(out string s) throws Exception1; +}; + +// +// TEST: Remove exception +// +class BaseClass7 +{ + void baseOp(); + void baseOp2(int i, out string s); +}; + +// +// TEST: Remove operation +// +class BaseClass8 +{ + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class +// +class BaseClass9 extends EmptyClass1 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add interface +// +class BaseClass10 implements Interface1 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Add base class and interface +// +class BaseClass11 extends EmptyClass1 implements Interface1 +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Class with compact id +// +class Compact1(1) +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Derived from class with compact id +// +class Derived1 extends Compact1 +{ +}; + +// +// TEST: Same class names but different compact id +// +class Compact2(3) +{ + void baseOp(); + void baseOp2(int i, out string s) throws Exception1; +}; + +// +// TEST: Class with optional members. +// +class Optional0 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; +}; + +// +// TEST: Class with optional members, different order, same tags. +// +class Optional1 +{ + string firstName; + optional(2) string emailAddress; + optional(1) string secondName; +}; + +// +// TEST: Class with different optional members. +// +class Optional2 +{ + string firstName; + optional(1) string secondName; + string emailAddress; +}; + +// +// TEST: Class with different optional members. +// +class Optional3 +{ + string firstName; + optional(1) string secondName; + optional(2) string emailAddress; + optional(3) string phoneNumber; +}; + +// +// TEST: Class with optional members using different tags. +// +class Optional4 +{ + string firstName; + optional(2) string secondName; + optional(1) string emailAddress; +}; + +// +// TEST: Class with optional parameters. +// +class OptionalParameters0 +{ + void op1(string firstName, optional(1) string secondName, + optional(2) string emailAddress); +}; + +// +// TEST: Class with optional parameters, different order. +// +class OptionalParameters1 +{ + void op1(string firstName, optional(2) string emailAddress, + optional(1) string secondName); +}; + +// +// TEST: Class with optional parameters, different tags. +// +class OptionalParameters2 +{ + void op1(string firstName, optional(2) string emailAddress, + optional(1) string secondName); +}; + +// +// TEST: Class with different optional parameters. +// +class OptionalParameters3 +{ + void op1(string firstName, string emailAddress, + optional(1) string secondName); +}; + +// +// TEST: Class with optional return type. +// +class OptionalReturn0 +{ + optional(1) int op(); +}; + +// +// TEST: Class that changes optional return type. +// +class OptionalReturn2 +{ + int op(); +}; + +// +// TEST: Local +// +local enum LocalEnum { LocalEnum1, LocalEnum2, LocalEnum3 }; + +// +// TEST: Local +// +local sequence<string> LocalSequence; + +// +// TEST: Local +// +local dictionary<string, string> LocalDictionary; + +// +// TEST: Local +// +local struct LocalStruct +{ + string str; +}; + +// +// TEST: Local +// +local class LocalClass +{ +}; + +}; diff --git a/python/test/Ice/checksum/Server.py b/python/test/Ice/checksum/Server.py new file mode 100755 index 00000000000..424df6a4826 --- /dev/null +++ b/python/test/Ice/checksum/Server.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' --checksum Test.ice STypes.ice") +import Test + +class ChecksumI(Test.Checksum): + def getSliceChecksums(self, current=None): + return Ice.sliceChecksums + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = ChecksumI() + adapter.add(object, communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/checksum/Test.ice b/python/test/Ice/checksum/Test.ice new file mode 100644 index 00000000000..21639acff0f --- /dev/null +++ b/python/test/Ice/checksum/Test.ice @@ -0,0 +1,24 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/SliceChecksumDict.ice> + +module Test +{ + +interface Checksum +{ + idempotent Ice::SliceChecksumDict getSliceChecksums(); + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/checksum/run.py b/python/test/Ice/checksum/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/checksum/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/custom/AllTests.py b/python/test/Ice/custom/AllTests.py new file mode 100644 index 00000000000..dd3a1437f90 --- /dev/null +++ b/python/test/Ice/custom/AllTests.py @@ -0,0 +1,118 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, string, re, traceback, Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + ref = "test:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + + custom = Test.CustomPrx.checkedCast(base) + test(custom) + + byteList = [1, 2, 3, 4, 5] + if sys.version_info[0] == 2: + byteString = ''.join(map(chr, byteList)) + else: + byteString = bytes(byteList) + stringList = ['s1', 's2', 's3'] + + sys.stdout.write("testing custom sequences... ") + sys.stdout.flush() + + (r, b2) = custom.opByteString1(byteString) + if sys.version_info[0] == 2: + test(isinstance(r, str)) + test(isinstance(b2, str)) + else: + test(isinstance(r, bytes)) + test(isinstance(b2, bytes)) + test(r == byteString) + test(b2 == byteString) + + (r, b2) = custom.opByteString2(byteString) + test(isinstance(r, tuple)) + test(isinstance(b2, list)) + for i in range(0, len(byteList)): + test(r[i] == byteList[i]) + test(b2[i] == byteList[i]) + + (r, b2) = custom.opByteList1(byteList) + test(isinstance(r, list)) + test(isinstance(b2, list)) + for i in range(0, len(byteList)): + test(r[i] == byteList[i]) + test(b2[i] == byteList[i]) + + (r, b2) = custom.opByteList2(byteList) + if sys.version_info[0] == 2: + test(isinstance(r, str)) + else: + test(isinstance(r, bytes)) + test(isinstance(b2, tuple)) + test(r == byteString) + for i in range(0, len(byteList)): + test(b2[i] == byteList[i]) + + (r, b2) = custom.opStringList1(stringList) + test(isinstance(r, list)) + test(isinstance(b2, list)) + test(r == stringList) + test(b2 == stringList) + + (r, b2) = custom.opStringList2(stringList) + test(isinstance(r, tuple)) + test(isinstance(b2, tuple)) + for i in range(0, len(stringList)): + test(r[i] == stringList[i]) + test(b2[i] == stringList[i]) + + (r, b2) = custom.opStringTuple1(stringList) + test(isinstance(r, tuple)) + test(isinstance(b2, tuple)) + for i in range(0, len(stringList)): + test(r[i] == stringList[i]) + test(b2[i] == stringList[i]) + + (r, b2) = custom.opStringTuple2(stringList) + test(isinstance(r, list)) + test(isinstance(b2, list)) + test(r == stringList) + test(b2 == stringList) + + s = Test.S() + s.b1 = byteList; + s.b2 = byteList; + s.b3 = byteList; + s.b4 = byteList; + s.s1 = stringList; + s.s2 = stringList; + s.s3 = stringList; + s.s4 = stringList; + custom.sendS(s) + + c = Test.C() + c.b1 = byteList; + c.b2 = byteList; + c.b3 = byteList; + c.b4 = byteList; + c.s1 = stringList; + c.s2 = stringList; + c.s3 = stringList; + c.s4 = stringList; + custom.sendC(c) + + print("ok") + + return custom diff --git a/python/test/Ice/custom/Client.py b/python/test/Ice/custom/Client.py new file mode 100755 index 00000000000..bce846df40f --- /dev/null +++ b/python/test/Ice/custom/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, AllTests + +def run(args, communicator): + custom = AllTests.allTests(communicator) + custom.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/custom/Server.py b/python/test/Ice/custom/Server.py new file mode 100755 index 00000000000..af0f49ebb76 --- /dev/null +++ b/python/test/Ice/custom/Server.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CustomI(Test.Custom): + def opByteString1(self, b1, current=None): + if sys.version_info[0] == 2: + test(isinstance(b1, str)) + else: + test(isinstance(b1, bytes)) + return (b1, b1) + + def opByteString2(self, b1, current=None): + test(isinstance(b1, list)) + return (b1, b1) + + def opByteList1(self, b1, current=None): + test(isinstance(b1, list)) + return (b1, b1) + + def opByteList2(self, b1, current=None): + test(isinstance(b1, tuple)) + return (b1, b1) + + def opStringList1(self, s1, current=None): + test(isinstance(s1, list)) + return (s1, s1) + + def opStringList2(self, s1, current=None): + test(isinstance(s1, tuple)) + return (s1, s1) + + def opStringTuple1(self, s1, current=None): + test(isinstance(s1, tuple)) + return (s1, s1) + + def opStringTuple2(self, s1, current=None): + test(isinstance(s1, list)) + return (s1, s1) + + def sendS(self, val, current=None): + if sys.version_info[0] == 2: + test(isinstance(val.b1, str)) + else: + test(isinstance(val.b1, bytes)) + test(isinstance(val.b2, list)) + if sys.version_info[0] == 2: + test(isinstance(val.b3, str)) + else: + test(isinstance(val.b3, bytes)) + test(isinstance(val.b4, list)) + test(isinstance(val.s1, list)) + test(isinstance(val.s2, tuple)) + test(isinstance(val.s3, tuple)) + test(isinstance(val.s4, list)) + + def sendC(self, val, current=None): + if sys.version_info[0] == 2: + test(isinstance(val.b1, str)) + else: + test(isinstance(val.b1, bytes)) + test(isinstance(val.b2, list)) + if sys.version_info[0] == 2: + test(isinstance(val.b3, str)) + else: + test(isinstance(val.b3, bytes)) + test(isinstance(val.b4, list)) + test(isinstance(val.s1, list)) + test(isinstance(val.s2, tuple)) + test(isinstance(val.s3, tuple)) + test(isinstance(val.s4, list)) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = CustomI() + adapter.add(object, communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/custom/Test.ice b/python/test/Ice/custom/Test.ice new file mode 100644 index 00000000000..aa68e90f1c3 --- /dev/null +++ b/python/test/Ice/custom/Test.ice @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + sequence<byte> ByteString; /* By default, sequence<byte> is received as a string. */ + ["python:seq:list"] sequence<byte> ByteList; + + sequence<string> StringList; /* By default, a sequence is received as a list. */ + ["python:seq:tuple"] sequence<string> StringTuple; + + struct S + { + ByteString b1; + ["python:seq:list"] ByteString b2; + ["python:seq:default"] ByteList b3; + ByteList b4; + StringList s1; + ["python:seq:tuple"] StringList s2; + StringTuple s3; + ["python:seq:default"] StringTuple s4; + }; + + class C + { + ByteString b1; + ["python:seq:list"] ByteString b2; + ["python:seq:default"] ByteList b3; + ByteList b4; + StringList s1; + ["python:seq:tuple"] StringList s2; + StringTuple s3; + ["python:seq:default"] StringTuple s4; + }; + + interface Custom + { + ByteString opByteString1(ByteString b1, out ByteString b2); + ["python:seq:tuple"] ByteString opByteString2(["python:seq:list"] ByteString b1, + out ["python:seq:list"] ByteString b2); + + ByteList opByteList1(ByteList b1, out ByteList b2); + ["python:seq:default"] ByteList opByteList2(["python:seq:tuple"] ByteList b1, + out ["python:seq:tuple"] ByteList b2); + + StringList opStringList1(StringList s1, out StringList s2); + ["python:seq:tuple"] StringList opStringList2(["python:seq:tuple"] StringList s1, + out ["python:seq:tuple"] StringList s2); + + StringTuple opStringTuple1(StringTuple s1, out StringTuple s2); + ["python:seq:list"] StringTuple opStringTuple2(["python:seq:list"] StringTuple s1, + out ["python:seq:default"] StringTuple s2); + + void sendS(S val); + void sendC(C val); + + void shutdown(); + }; +}; diff --git a/python/test/Ice/custom/run.py b/python/test/Ice/custom/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/custom/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/defaultServant/AllTests.py b/python/test/Ice/defaultServant/AllTests.py new file mode 100644 index 00000000000..2b3e1533d84 --- /dev/null +++ b/python/test/Ice/defaultServant/AllTests.py @@ -0,0 +1,126 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, MyObjectI, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + + oa = communicator.createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost") + oa.activate() + + servant = MyObjectI.MyObjectI() + + # Register default servant with category "foo" + oa.addDefaultServant(servant, "foo") + + # Start test + sys.stdout.write("testing single category... ") + sys.stdout.flush() + + r = oa.findDefaultServant("foo") + test(r == servant) + + r = oa.findDefaultServant("bar") + test(r == None) + + identity = Ice.Identity() + identity.category = "foo" + + names = ( "foo", "bar", "x", "y", "abcdefg" ) + + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + prx.ice_ping() + test(prx.getName() == names[idx]) + + identity.name = "ObjectNotExist" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + identity.name = "FacetNotExist" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + test(false) + except Ice.FacetNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.FacetNotExistException: + # Expected + pass + + identity.category = "bar" + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + + try: + prx.ice_ping() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + try: + prx.getName() + test(false) + except Ice.ObjectNotExistException: + # Expected + pass + + oa.removeDefaultServant("foo") + identity.category = "foo" + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + try: + prx.ice_ping() + except Ice.ObjectNotExistException: + # Expected + pass + + print("ok") + + sys.stdout.write("testing default category... ") + sys.stdout.flush() + + oa.addDefaultServant(servant, "") + + r = oa.findDefaultServant("bar") + test(r == None) + + r = oa.findDefaultServant("") + test(r == servant) + + for idx in range(0, 5): + identity.name = names[idx] + prx = Test.MyObjectPrx.uncheckedCast(oa.createProxy(identity)) + prx.ice_ping() + test(prx.getName() == names[idx]) + + print("ok") diff --git a/python/test/Ice/defaultServant/Client.py b/python/test/Ice/defaultServant/Client.py new file mode 100755 index 00000000000..7cc8180a8fc --- /dev/null +++ b/python/test/Ice/defaultServant/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import AllTests + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/defaultServant/MyObjectI.py b/python/test/Ice/defaultServant/MyObjectI.py new file mode 100644 index 00000000000..97cbd4bbf3d --- /dev/null +++ b/python/test/Ice/defaultServant/MyObjectI.py @@ -0,0 +1,29 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test + +class MyObjectI(Test.MyObject): + def ice_ping(self, current=None): + name = current.id.name + + if name == "ObjectNotExist": + raise Ice.ObjectNotExistException() + elif name == "FacetNotExist": + raise Ice.FacetNotExistException() + + def getName(self, current=None): + name = current.id.name + + if name == "ObjectNotExist": + raise Ice.ObjectNotExistException() + elif name == "FacetNotExist": + raise Ice.FacetNotExistException() + + return name diff --git a/python/test/Ice/defaultServant/Test.ice b/python/test/Ice/defaultServant/Test.ice new file mode 100644 index 00000000000..cc90e550721 --- /dev/null +++ b/python/test/Ice/defaultServant/Test.ice @@ -0,0 +1,20 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface MyObject +{ + string getName(); +}; + +}; diff --git a/python/test/Ice/defaultServant/run.py b/python/test/Ice/defaultServant/run.py new file mode 100755 index 00000000000..4268e9283e0 --- /dev/null +++ b/python/test/Ice/defaultServant/run.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", startReader = False) +print("ok") +clientProc.startReader() + +clientProc.waitTestSuccess() diff --git a/python/test/Ice/defaultValue/AllTests.py b/python/test/Ice/defaultValue/AllTests.py new file mode 100644 index 00000000000..bc529c4b90e --- /dev/null +++ b/python/test/Ice/defaultValue/AllTests.py @@ -0,0 +1,184 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(): + + sys.stdout.write("testing default values... ") + sys.stdout.flush() + + v = Test.Struct1() + test(not v.boolFalse) + test(v.boolTrue) + test(v.b == 254) + test(v.s == 16000) + test(v.i == 3) + test(v.l == 4) + test(v.f == 5.1) + test(v.d == 6.2) + test(v.str == "foo \\ \"bar\n \r\n\t\013\f\007\b? \007 \007") + test(v.c1 == Test.Color.red) + test(v.c2 == Test.Color.green) + test(v.c3 == Test.Color.blue) + test(v.nc1 == Test.Nested.Color.red) + test(v.nc2 == Test.Nested.Color.green) + test(v.nc3 == Test.Nested.Color.blue) + test(v.noDefault == '') + test(v.zeroI == 0) + test(v.zeroL == 0) + test(v.zeroF == 0) + test(v.zeroDotF == 0) + test(v.zeroD == 0) + test(v.zeroDotD == 0) + + v = Test.Struct2() + test(v.boolTrue == Test.ConstBool) + test(v.b == Test.ConstByte) + test(v.s == Test.ConstShort) + test(v.i == Test.ConstInt) + test(v.l == Test.ConstLong) + test(v.f == Test.ConstFloat) + test(v.d == Test.ConstDouble) + test(v.str == Test.ConstString) + test(v.c1 == Test.ConstColor1) + test(v.c2 == Test.ConstColor2) + test(v.c3 == Test.ConstColor3) + test(v.nc1 == Test.ConstNestedColor1) + test(v.nc2 == Test.ConstNestedColor2) + test(v.nc3 == Test.ConstNestedColor3) + test(v.zeroI == Test.ConstZeroI) + test(v.zeroL == Test.ConstZeroL) + test(v.zeroF == Test.ConstZeroF) + test(v.zeroDotF == Test.ConstZeroDotF) + test(v.zeroD == Test.ConstZeroD) + test(v.zeroDotD == Test.ConstZeroDotD) + + v = Test.Base() + test(not v.boolFalse) + test(v.boolTrue) + test(v.b == 1) + test(v.s == 2) + test(v.i == 3) + test(v.l == 4) + test(v.f == 5.1) + test(v.d == 6.2) + test(v.str == "foo \\ \"bar\n \r\n\t\013\f\007\b? \007 \007") + test(v.noDefault == '') + test(v.zeroI == 0) + test(v.zeroL == 0) + test(v.zeroF == 0) + test(v.zeroDotF == 0) + test(v.zeroD == 0) + test(v.zeroDotD == 0) + + v = Test.Derived() + test(not v.boolFalse) + test(v.boolTrue) + test(v.b == 1) + test(v.s == 2) + test(v.i == 3) + test(v.l == 4) + test(v.f == 5.1) + test(v.d == 6.2) + test(v.str == "foo \\ \"bar\n \r\n\t\013\f\007\b? \007 \007") + test(v.c1 == Test.Color.red) + test(v.c2 == Test.Color.green) + test(v.c3 == Test.Color.blue) + test(v.nc1 == Test.Nested.Color.red) + test(v.nc2 == Test.Nested.Color.green) + test(v.nc3 == Test.Nested.Color.blue) + test(v.noDefault == '') + test(v.zeroI == 0) + test(v.zeroL == 0) + test(v.zeroF == 0) + test(v.zeroDotF == 0) + test(v.zeroD == 0) + test(v.zeroDotD == 0) + + v = Test.BaseEx() + test(not v.boolFalse) + test(v.boolTrue) + test(v.b == 1) + test(v.s == 2) + test(v.i == 3) + test(v.l == 4) + test(v.f == 5.1) + test(v.d == 6.2) + test(v.str == "foo \\ \"bar\n \r\n\t\013\f\007\b? \007 \007") + test(v.noDefault == '') + test(v.zeroI == 0) + test(v.zeroL == 0) + test(v.zeroF == 0) + test(v.zeroDotF == 0) + test(v.zeroD == 0) + test(v.zeroDotD == 0) + + v = Test.DerivedEx() + test(not v.boolFalse) + test(v.boolTrue) + test(v.b == 1) + test(v.s == 2) + test(v.i == 3) + test(v.l == 4) + test(v.f == 5.1) + test(v.d == 6.2) + test(v.str == "foo \\ \"bar\n \r\n\t\013\f\007\b? \007 \007") + test(v.noDefault == '') + test(v.c1 == Test.Color.red) + test(v.c2 == Test.Color.green) + test(v.c3 == Test.Color.blue) + test(v.nc1 == Test.Nested.Color.red) + test(v.nc2 == Test.Nested.Color.green) + test(v.nc3 == Test.Nested.Color.blue) + test(v.zeroI == 0) + test(v.zeroL == 0) + test(v.zeroF == 0) + test(v.zeroDotF == 0) + test(v.zeroD == 0) + test(v.zeroDotD == 0) + + print("ok") + + sys.stdout.write("testing default constructor... ") + sys.stdout.flush() + v = Test.StructNoDefaults() + test(v.bo == False) + test(v.b == 0) + test(v.s == 0) + test(v.i == 0) + test(v.l == 0) + test(v.f == 0.0) + test(v.d == 0.0) + test(v.str == '') + test(v.c1 == Test.Color.red) + test(v.bs is None) + test(v.iseq is None) + test(isinstance(v.st, Test.InnerStruct)); + test(v.dict is None); + + e = Test.ExceptionNoDefaults() + test(e.str == '') + test(e.c1 == Test.Color.red) + test(e.bs is None) + test(isinstance(e.st, Test.InnerStruct)); + test(e.dict is None); + + c = Test.ClassNoDefaults() + test(c.str == '') + test(c.c1 == Test.Color.red) + test(c.bs is None) + test(isinstance(c.st, Test.InnerStruct)); + test(c.dict is None); + + print("ok") diff --git a/python/test/Ice/defaultValue/Client.py b/python/test/Ice/defaultValue/Client.py new file mode 100755 index 00000000000..061672f46dc --- /dev/null +++ b/python/test/Ice/defaultValue/Client.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import AllTests + +def run(args): + AllTests.allTests() + return True + +try: + status = run(sys.argv) +except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/defaultValue/Test.ice b/python/test/Ice/defaultValue/Test.ice new file mode 100644 index 00000000000..101a42883f3 --- /dev/null +++ b/python/test/Ice/defaultValue/Test.ice @@ -0,0 +1,208 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +enum Color { red, green, blue }; + +module Nested +{ + +enum Color { red, green, blue }; + +}; + + +struct Struct1 +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 254; + short s = 16000; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\? \007 \x07"; + Color c1 = ::Test::red; + Color c2 = Test::green; + Color c3 = blue; + Nested::Color nc1 = ::Test::Nested::red; + Nested::Color nc2 = Nested::green; + Nested::Color nc3 = Nested::blue; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +}; + +const bool ConstBool = true; +const byte ConstByte = 254; +const short ConstShort = 16000; +const int ConstInt = 3; +const long ConstLong = 4; +const float ConstFloat = 5.1; +const double ConstDouble = 6.2; +const string ConstString = "foo \\ \"bar\n \r\n\t\v\f\a\b\? \007 \x07"; +const Color ConstColor1 = ::Test::red; +const Color ConstColor2 = Test::green; +const Color ConstColor3 = blue; +const Nested::Color ConstNestedColor1 = ::Test::Nested::red; +const Nested::Color ConstNestedColor2 = Test::Nested::green; +const Nested::Color ConstNestedColor3 = Nested::blue; +const int ConstZeroI = 0; +const long ConstZeroL = 0; +const float ConstZeroF = 0; +const float ConstZeroDotF = 0.0; +const double ConstZeroD = 0; +const double ConstZeroDotD = 0; + +struct Struct2 +{ + bool boolTrue = ConstBool; + byte b = ConstByte; + short s = ConstShort; + int i = ConstInt; + long l = ConstLong; + float f = ConstFloat; + double d = ConstDouble; + string str = ConstString; + Color c1 = ConstColor1; + Color c2 = ConstColor2; + Color c3 = ConstColor3; + Nested::Color nc1 = ConstNestedColor1; + Nested::Color nc2 = ConstNestedColor2; + Nested::Color nc3 = ConstNestedColor3; + int zeroI = ConstZeroI; + long zeroL = ConstZeroL; + float zeroF = ConstZeroF; + float zeroDotF = ConstZeroDotF; + double zeroD = ConstZeroD; + double zeroDotD = ConstZeroDotD; +}; + +class Base +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 1; + short s = 2; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\? \007 \x07"; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +}; + +class Derived extends Base +{ + Color c1 = ::Test::red; + Color c2 = Test::green; + Color c3 = blue; + Nested::Color nc1 = ::Test::Nested::red; + Nested::Color nc2 = Nested::green; + Nested::Color nc3 = Nested::blue; +}; + +exception BaseEx +{ + bool boolFalse = false; + bool boolTrue = true; + byte b = 1; + short s = 2; + int i = 3; + long l = 4; + float f = 5.1; + double d = 6.2; + string str = "foo \\ \"bar\n \r\n\t\v\f\a\b\? \007 \x07"; + string noDefault; + int zeroI = 0; + long zeroL = 0; + float zeroF = 0; + float zeroDotF = 0.0; + double zeroD = 0; + double zeroDotD = 0; +}; + +exception DerivedEx extends BaseEx +{ + Color c1 = ConstColor1; + Color c2 = ConstColor2; + Color c3 = ConstColor3; + Nested::Color nc1 = ConstNestedColor1; + Nested::Color nc2 = ConstNestedColor2; + Nested::Color nc3 = ConstNestedColor3; +}; + +sequence<byte> ByteSeq; +sequence<int> IntSeq; +dictionary<int, string> IntStringDict; + +struct InnerStruct +{ + int a; +}; + +struct StructNoDefaults +{ + bool bo; + byte b; + short s; + int i; + long l; + float f; + double d; + string str; + Color c1; + ByteSeq bs; + IntSeq iseq; + IntStringDict dict; + InnerStruct st; +}; + +exception ExceptionNoDefaultsBase +{ + string str; + Color c1; + ByteSeq bs; +}; + +exception ExceptionNoDefaults extends ExceptionNoDefaultsBase +{ + InnerStruct st; + IntStringDict dict; +}; + +class ClassNoDefaultsBase +{ + string str; + Color c1; + ByteSeq bs; +}; + +class ClassNoDefaults extends ClassNoDefaultsBase +{ + InnerStruct st; + IntStringDict dict; +}; + +}; diff --git a/python/test/Ice/defaultValue/run.py b/python/test/Ice/defaultValue/run.py new file mode 100755 index 00000000000..4268e9283e0 --- /dev/null +++ b/python/test/Ice/defaultValue/run.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", startReader = False) +print("ok") +clientProc.startReader() + +clientProc.waitTestSuccess() diff --git a/python/test/Ice/enums/AllTests.py b/python/test/Ice/enums/AllTests.py new file mode 100644 index 00000000000..a5dae46cff9 --- /dev/null +++ b/python/test/Ice/enums/AllTests.py @@ -0,0 +1,128 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, string, re, traceback, Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + ref = "test:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + + proxy = Test.TestIntfPrx.checkedCast(base) + test(proxy) + + sys.stdout.write("testing enum values... ") + sys.stdout.flush() + + test(Test.ByteEnum.benum1.value == 0); + test(Test.ByteEnum.benum2.value == 1); + test(Test.ByteEnum.benum3.value == Test.ByteConst1); + test(Test.ByteEnum.benum4.value == Test.ByteConst1 + 1); + test(Test.ByteEnum.benum5.value == Test.ShortConst1); + test(Test.ByteEnum.benum6.value == Test.ShortConst1 + 1); + test(Test.ByteEnum.benum7.value == Test.IntConst1); + test(Test.ByteEnum.benum8.value == Test.IntConst1 + 1); + test(Test.ByteEnum.benum9.value == Test.LongConst1); + test(Test.ByteEnum.benum10.value == Test.LongConst1 + 1); + test(Test.ByteEnum.benum11.value == Test.ByteConst2); + + test(Test.ByteEnum.valueOf(0) == Test.ByteEnum.benum1); + test(Test.ByteEnum.valueOf(1) == Test.ByteEnum.benum2); + test(Test.ByteEnum.valueOf(Test.ByteConst1) == Test.ByteEnum.benum3); + test(Test.ByteEnum.valueOf(Test.ByteConst1 + 1) == Test.ByteEnum.benum4); + test(Test.ByteEnum.valueOf(Test.ShortConst1) == Test.ByteEnum.benum5); + test(Test.ByteEnum.valueOf(Test.ShortConst1 + 1) == Test.ByteEnum.benum6); + test(Test.ByteEnum.valueOf(Test.IntConst1) == Test.ByteEnum.benum7); + test(Test.ByteEnum.valueOf(Test.IntConst1 + 1) == Test.ByteEnum.benum8); + test(Test.ByteEnum.valueOf(Test.LongConst1) == Test.ByteEnum.benum9); + test(Test.ByteEnum.valueOf(Test.LongConst1 + 1) == Test.ByteEnum.benum10); + test(Test.ByteEnum.valueOf(Test.ByteConst2) == Test.ByteEnum.benum11); + + test(Test.ShortEnum.senum1.value == 3); + test(Test.ShortEnum.senum2.value == 4); + test(Test.ShortEnum.senum3.value == Test.ByteConst1); + test(Test.ShortEnum.senum4.value == Test.ByteConst1 + 1); + test(Test.ShortEnum.senum5.value == Test.ShortConst1); + test(Test.ShortEnum.senum6.value == Test.ShortConst1 + 1); + test(Test.ShortEnum.senum7.value == Test.IntConst1); + test(Test.ShortEnum.senum8.value == Test.IntConst1 + 1); + test(Test.ShortEnum.senum9.value == Test.LongConst1); + test(Test.ShortEnum.senum10.value == Test.LongConst1 + 1); + test(Test.ShortEnum.senum11.value == Test.ShortConst2); + + test(Test.ShortEnum.valueOf(3) == Test.ShortEnum.senum1); + test(Test.ShortEnum.valueOf(4) == Test.ShortEnum.senum2); + test(Test.ShortEnum.valueOf(Test.ByteConst1) == Test.ShortEnum.senum3); + test(Test.ShortEnum.valueOf(Test.ByteConst1 + 1) == Test.ShortEnum.senum4); + test(Test.ShortEnum.valueOf(Test.ShortConst1) == Test.ShortEnum.senum5); + test(Test.ShortEnum.valueOf(Test.ShortConst1 + 1) == Test.ShortEnum.senum6); + test(Test.ShortEnum.valueOf(Test.IntConst1) == Test.ShortEnum.senum7); + test(Test.ShortEnum.valueOf(Test.IntConst1 + 1) == Test.ShortEnum.senum8); + test(Test.ShortEnum.valueOf(Test.LongConst1) == Test.ShortEnum.senum9); + test(Test.ShortEnum.valueOf(Test.LongConst1 + 1) == Test.ShortEnum.senum10); + test(Test.ShortEnum.valueOf(Test.ShortConst2) == Test.ShortEnum.senum11); + + test(Test.IntEnum.ienum1.value == 0); + test(Test.IntEnum.ienum2.value == 1); + test(Test.IntEnum.ienum3.value == Test.ByteConst1); + test(Test.IntEnum.ienum4.value == Test.ByteConst1 + 1); + test(Test.IntEnum.ienum5.value == Test.ShortConst1); + test(Test.IntEnum.ienum6.value == Test.ShortConst1 + 1); + test(Test.IntEnum.ienum7.value == Test.IntConst1); + test(Test.IntEnum.ienum8.value == Test.IntConst1 + 1); + test(Test.IntEnum.ienum9.value == Test.LongConst1); + test(Test.IntEnum.ienum10.value == Test.LongConst1 + 1); + test(Test.IntEnum.ienum11.value == Test.IntConst2); + test(Test.IntEnum.ienum12.value == Test.LongConst2); + + test(Test.IntEnum.valueOf(0) == Test.IntEnum.ienum1); + test(Test.IntEnum.valueOf(1) == Test.IntEnum.ienum2); + test(Test.IntEnum.valueOf(Test.ByteConst1) == Test.IntEnum.ienum3); + test(Test.IntEnum.valueOf(Test.ByteConst1 + 1) == Test.IntEnum.ienum4); + test(Test.IntEnum.valueOf(Test.ShortConst1) == Test.IntEnum.ienum5); + test(Test.IntEnum.valueOf(Test.ShortConst1 + 1) == Test.IntEnum.ienum6); + test(Test.IntEnum.valueOf(Test.IntConst1) == Test.IntEnum.ienum7); + test(Test.IntEnum.valueOf(Test.IntConst1 + 1) == Test.IntEnum.ienum8); + test(Test.IntEnum.valueOf(Test.LongConst1) == Test.IntEnum.ienum9); + test(Test.IntEnum.valueOf(Test.LongConst1 + 1) == Test.IntEnum.ienum10); + test(Test.IntEnum.valueOf(Test.IntConst2) == Test.IntEnum.ienum11); + test(Test.IntEnum.valueOf(Test.LongConst2) == Test.IntEnum.ienum12); + + test(Test.SimpleEnum.red.value == 0); + test(Test.SimpleEnum.green.value == 1); + test(Test.SimpleEnum.blue.value == 2); + + test(Test.SimpleEnum.valueOf(0) == Test.SimpleEnum.red); + test(Test.SimpleEnum.valueOf(1) == Test.SimpleEnum.green); + test(Test.SimpleEnum.valueOf(2) == Test.SimpleEnum.blue); + + print("ok") + + sys.stdout.write("testing enum operations... ") + sys.stdout.flush() + + test(proxy.opByte(Test.ByteEnum.benum1) == (Test.ByteEnum.benum1, Test.ByteEnum.benum1)); + test(proxy.opByte(Test.ByteEnum.benum11) == (Test.ByteEnum.benum11, Test.ByteEnum.benum11)); + + test(proxy.opShort(Test.ShortEnum.senum1) == (Test.ShortEnum.senum1, Test.ShortEnum.senum1)); + test(proxy.opShort(Test.ShortEnum.senum11) == (Test.ShortEnum.senum11, Test.ShortEnum.senum11)); + + test(proxy.opInt(Test.IntEnum.ienum1) == (Test.IntEnum.ienum1, Test.IntEnum.ienum1)); + test(proxy.opInt(Test.IntEnum.ienum11) == (Test.IntEnum.ienum11, Test.IntEnum.ienum11)); + test(proxy.opInt(Test.IntEnum.ienum12) == (Test.IntEnum.ienum12, Test.IntEnum.ienum12)); + + test(proxy.opSimple(Test.SimpleEnum.green) == (Test.SimpleEnum.green, Test.SimpleEnum.green)); + + print("ok") + + return proxy diff --git a/python/test/Ice/enums/Client.py b/python/test/Ice/enums/Client.py new file mode 100755 index 00000000000..acff619e914 --- /dev/null +++ b/python/test/Ice/enums/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, AllTests + +def run(args, communicator): + proxy = AllTests.allTests(communicator) + proxy.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/enums/Server.py b/python/test/Ice/enums/Server.py new file mode 100755 index 00000000000..f51922e12fc --- /dev/null +++ b/python/test/Ice/enums/Server.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestIntfI(Test.TestIntf): + def opByte(self, b1, current=None): + return (b1, b1) + + def opShort(self, s1, current=None): + return (s1, s1) + + def opInt(self, i1, current=None): + return (i1, i1) + + def opSimple(self, s1, current=None): + return (s1, s1) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestIntfI() + adapter.add(object, communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/enums/Test.ice b/python/test/Ice/enums/Test.ice new file mode 100644 index 00000000000..1cfe8c3eda8 --- /dev/null +++ b/python/test/Ice/enums/Test.ice @@ -0,0 +1,88 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +const byte ByteConst1 = 10; +const short ShortConst1 = 20; +const int IntConst1 = 30; +const long LongConst1 = 40; + +const byte ByteConst2 = 126; +const short ShortConst2 = 32766; +const int IntConst2 = 2147483647; +const long LongConst2 = 2147483646; + +enum ByteEnum +{ + benum1, + benum2, + benum3 = ByteConst1, + benum4, + benum5 = ShortConst1, + benum6, + benum7 = IntConst1, + benum8, + benum9 = LongConst1, + benum10, + benum11 = ByteConst2 +}; + +enum ShortEnum +{ + senum1 = 3, + senum2, + senum3 = ByteConst1, + senum4, + senum5 = ShortConst1, + senum6, + senum7 = IntConst1, + senum8, + senum9 = LongConst1, + senum10, + senum11 = ShortConst2 +}; + +enum IntEnum +{ + ienum1, + ienum2, + ienum3 = ByteConst1, + ienum4, + ienum5 = ShortConst1, + ienum6, + ienum7 = IntConst1, + ienum8, + ienum9 = LongConst1, + ienum10, + ienum11 = IntConst2, + ienum12 = LongConst2 +}; + +enum SimpleEnum +{ + red, + green, + blue +}; + +interface TestIntf +{ + ByteEnum opByte(ByteEnum b1, out ByteEnum b2); + ShortEnum opShort(ShortEnum s1, out ShortEnum s2); + IntEnum opInt(IntEnum i1, out IntEnum i2); + SimpleEnum opSimple(SimpleEnum s1, out SimpleEnum s2); + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/enums/run.py b/python/test/Ice/enums/run.py new file mode 100755 index 00000000000..614bfe363bf --- /dev/null +++ b/python/test/Ice/enums/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running test with 1.1 encoding.") +TestUtil.clientServerTest() diff --git a/python/test/Ice/exceptions/AllTests.py b/python/test/Ice/exceptions/AllTests.py new file mode 100644 index 00000000000..4522a0de731 --- /dev/null +++ b/python/test/Ice/exceptions/AllTests.py @@ -0,0 +1,721 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, threading, sys, array + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class EmptyI(Test.Empty): + pass + +class ServantLocatorI(Ice.ServantLocator): + def locate(self, current): + return None + + def finished(self, current, servant, cookie): + pass + + def deactivate(self, category): + pass + +class ObjectFactoryI(Ice.ObjectFactory): + def create(id): + return None + + def destroy(): + pass + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def __init__(self, communicator=None): + CallbackBase.__init__(self) + self._communicator = communicator + + def response(self): + test(False) + + def exception_AasA(self, ex): + test(isinstance(ex, Test.A)) + test(ex.aMem == 1) + self.called() + + def exception_AorDasAorD(self, ex): + try: + raise ex + except Test.A as ex: + test(ex.aMem == 1) + except Test.D as ex: + test(ex.dMem == -1) + except: + test(False) + self.called() + + def exception_BasB(self, ex): + try: + raise ex + except Test.B as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + except: + test(False) + self.called() + + def exception_CasC(self, ex): + try: + raise ex + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + test(False) + self.called() + + def exception_ModA(self, ex): + try: + raise ex + except Test.Mod.A as ex: + test(ex.aMem == 1) + test(ex.a2Mem == 2) + except Ice.OperationNotExistException: + # + # This operation is not supported in Java. + # + pass + except: + test(False) + self.called() + + def exception_BasA(self, ex): + try: + raise ex + except Test.B as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + except: + test(False) + self.called() + + def exception_CasA(self, ex): + try: + raise ex + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + test(False) + self.called() + + def exception_CasB(self, ex): + try: + raise ex + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + test(False) + self.called() + + def exception_UndeclaredA(self, ex): + try: + raise ex + except Ice.UnknownUserException: + pass + except: + test(False) + self.called() + + def exception_UndeclaredB(self, ex): + try: + raise ex + except Ice.UnknownUserException: + pass + except: + test(False) + self.called() + + def exception_UndeclaredC(self, ex): + try: + raise ex + except Ice.UnknownUserException: + pass + except: + test(False) + self.called() + + def exception_AasAObjectNotExist(self, ex): + try: + raise ex + except Ice.ObjectNotExistException as ex: + id = self._communicator.stringToIdentity("does not exist") + test(ex.id == id) + except: + test(False) + self.called() + + def exception_AasAFacetNotExist(self, ex): + try: + raise ex + except Ice.FacetNotExistException as ex: + test(ex.facet == "no such facet") + except: + test(False) + self.called() + + def exception_noSuchOperation(self, ex): + try: + raise ex + except Ice.OperationNotExistException as ex: + test(ex.operation == "noSuchOperation") + except: + test(False) + self.called() + + def exception_LocalException(self, ex): + try: + raise ex + except Ice.UnknownLocalException as ex: + pass + except Ice.OperationNotExistException as ex: + pass + except: + test(False) + self.called() + + def exception_NonIceException(self, ex): + try: + raise ex + except Ice.UnknownException as ex: + pass + except: + test(False) + self.called() + +def allTests(communicator): + sys.stdout.write("testing servant registration exceptions... ") + sys.stdout.flush() + communicator.getProperties().setProperty("TestAdapter1.Endpoints", "default") + adapter = communicator.createObjectAdapter("TestAdapter1") + obj = EmptyI() + adapter.add(obj, communicator.stringToIdentity("x")) + try: + adapter.add(obj, communicator.stringToIdentity("x")) + test(false) + except Ice.AlreadyRegisteredException: + pass + + try: + adapter.add(obj, communicator.stringToIdentity("")) + test(false) + except Ice.IllegalIdentityException as ex: + test(ex.id.name == "") + + try: + adapter.add(None, communicator.stringToIdentity("x")) + test(false) + except Ice.IllegalServantException: + pass + + + adapter.remove(communicator.stringToIdentity("x")) + try: + adapter.remove(communicator.stringToIdentity("x")) + test(false) + except Ice.NotRegisteredException: + pass + + adapter.deactivate() + print("ok") + + sys.stdout.write("testing servant locator registrations exceptions... ") + sys.stdout.flush() + communicator.getProperties().setProperty("TestAdapter2.Endpoints", "default") + adapter = communicator.createObjectAdapter("TestAdapter2") + loc = ServantLocatorI() + adapter.addServantLocator(loc, "x") + try: + adapter.addServantLocator(loc, "x") + test(false) + except Ice.AlreadyRegisteredException: + pass + + adapter.deactivate() + print("ok") + + sys.stdout.write("testing object factory registration exception... ") + sys.stdout.flush() + of = ObjectFactoryI() + communicator.addObjectFactory(of, "x") + try: + communicator.addObjectFactory(of, "x") + test(false) + except Ice.AlreadyRegisteredException: + pass + print("ok") + + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "thrower:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + thrower = Test.ThrowerPrx.checkedCast(base) + test(thrower) + test(thrower == base) + print("ok") + + sys.stdout.write("catching exact types... ") + sys.stdout.flush() + + try: + thrower.throwAasA(1) + test(False) + except Test.A as ex: + test(ex.aMem == 1) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwAorDasAorD(1) + test(False) + except Test.A as ex: + test(ex.aMem == 1) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwAorDasAorD(-1) + test(False) + except Test.D as ex: + test(ex.dMem == -1) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwBasB(1, 2) + test(False) + except Test.B as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwCasC(1, 2, 3) + test(False) + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwModA(1, 2) + test(False) + except Test.Mod.A as ex: + test(ex.aMem == 1) + test(ex.a2Mem == 2) + except Ice.OperationNotExistException: + # + # This operation is not supported in Java. + # + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching base types... ") + sys.stdout.flush() + + try: + thrower.throwBasB(1, 2) + test(False) + except Test.A as ex: + test(ex.aMem == 1) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwCasC(1, 2, 3) + test(False) + except Test.B as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwModA(1, 2) + test(False) + except Test.A as ex: + test(ex.aMem == 1) + except Ice.OperationNotExistException: + # + # This operation is not supported in Java. + # + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching derived types... ") + sys.stdout.flush() + + try: + thrower.throwBasA(1, 2) + test(False) + except Test.B as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwCasA(1, 2, 3) + test(False) + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwCasB(1, 2, 3) + test(False) + except Test.C as ex: + test(ex.aMem == 1) + test(ex.bMem == 2) + test(ex.cMem == 3) + except: + print(sys.exc_info()) + test(False) + + print("ok") + + if thrower.supportsUndeclaredExceptions(): + sys.stdout.write("catching unknown user exception... ") + sys.stdout.flush() + + try: + thrower.throwUndeclaredA(1) + test(False) + except Ice.UnknownUserException: + pass + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwUndeclaredB(1, 2) + test(False) + except Ice.UnknownUserException: + pass + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwUndeclaredC(1, 2, 3) + test(False) + except Ice.UnknownUserException: + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + + if thrower.ice_getConnection(): + sys.stdout.write("testing memory limit marshal exception..."); + sys.stdout.flush(); + + try: + thrower.throwMemoryLimitException(array.array('B')); + test(False) + except Ice.MemoryLimitException: + pass + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwMemoryLimitException(bytearray(20 * 1024)) # 20KB + test(False) + except Ice.ConnectionLostException: + pass + except: + test(False) + + print("ok"); + + sys.stdout.write("catching object not exist exception... ") + sys.stdout.flush() + + id = communicator.stringToIdentity("does not exist") + try: + thrower2 = Test.ThrowerPrx.uncheckedCast(thrower.ice_identity(id)) + thrower2.throwAasA(1) +# thrower2.ice_ping() + test(False) + except Ice.ObjectNotExistException as ex: + test(ex.id == id) + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching facet not exist exception... ") + sys.stdout.flush() + + try: + thrower2 = Test.ThrowerPrx.uncheckedCast(thrower, "no such facet") + try: + thrower2.ice_ping() + test(False) + except Ice.FacetNotExistException as ex: + test(ex.facet == "no such facet") + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching operation not exist exception... ") + sys.stdout.flush() + + try: + thrower2 = Test.WrongOperationPrx.uncheckedCast(thrower) + thrower2.noSuchOperation() + test(False) + except Ice.OperationNotExistException as ex: + test(ex.operation == "noSuchOperation") + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching unknown local exception... ") + sys.stdout.flush() + + try: + thrower.throwLocalException() + test(False) + except Ice.UnknownLocalException: + pass + except: + print(sys.exc_info()) + test(False) + try: + thrower.throwLocalExceptionIdempotent() + test(False) + except Ice.UnknownLocalException: + pass + except Ice.OperationNotExistException: + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching unknown non-Ice exception... ") + sys.stdout.flush() + + try: + thrower.throwNonIceException() + test(False) + except Ice.UnknownException: + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("testing asynchronous exceptions... ") + sys.stdout.flush() + + try: + thrower.throwAfterResponse() + except: + print(sys.exc_info()) + test(False) + + try: + thrower.throwAfterException() + except Test.A: + pass + except: + print(sys.exc_info()) + test(False) + + print("ok") + + sys.stdout.write("catching exact types with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower.begin_throwAasA(1, cb.response, cb.exception_AasA) + cb.check() + + cb = Callback() + thrower.begin_throwAorDasAorD(1, cb.response, cb.exception_AorDasAorD) + cb.check() + + cb = Callback() + thrower.begin_throwAorDasAorD(-1, cb.response, cb.exception_AorDasAorD) + cb.check() + + cb = Callback() + thrower.begin_throwBasB(1, 2, cb.response, cb.exception_BasB) + cb.check() + + cb = Callback() + thrower.begin_throwCasC(1, 2, 3, cb.response, cb.exception_CasC) + cb.check() + + cb = Callback() + thrower.begin_throwModA(1, 2, cb.response, cb.exception_ModA) + cb.check() + + print("ok") + + sys.stdout.write("catching derived types with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower.begin_throwBasA(1, 2, cb.response, cb.exception_BasA) + cb.check() + + cb = Callback() + thrower.begin_throwCasA(1, 2, 3, cb.response, cb.exception_CasA) + cb.check() + + cb = Callback() + thrower.begin_throwCasB(1, 2, 3, cb.response, cb.exception_CasB) + cb.check() + + print("ok") + + if thrower.supportsUndeclaredExceptions(): + sys.stdout.write("catching unknown user exception with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower.begin_throwUndeclaredA(1, cb.response, cb.exception_UndeclaredA) + cb.check() + + cb = Callback() + thrower.begin_throwUndeclaredB(1, 2, cb.response, cb.exception_UndeclaredB) + cb.check() + + cb = Callback() + thrower.begin_throwUndeclaredC(1, 2, 3, cb.response, cb.exception_UndeclaredC) + cb.check() + + print("ok") + + sys.stdout.write("catching object not exist exception with AMI mapping... ") + sys.stdout.flush() + + id = communicator.stringToIdentity("does not exist") + thrower2 = Test.ThrowerPrx.uncheckedCast(thrower.ice_identity(id)) + cb = Callback(communicator) + thrower2.begin_throwAasA(1, cb.response, cb.exception_AasAObjectNotExist) + cb.check() + + print("ok") + + sys.stdout.write("catching facet not exist exception with AMI mapping... ") + sys.stdout.flush() + + thrower2 = Test.ThrowerPrx.uncheckedCast(thrower, "no such facet") + cb = Callback() + thrower2.begin_throwAasA(1, cb.response, cb.exception_AasAFacetNotExist) + cb.check() + + print("ok") + + sys.stdout.write("catching operation not exist exception with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower4 = Test.WrongOperationPrx.uncheckedCast(thrower) + thrower4.begin_noSuchOperation(cb.response, cb.exception_noSuchOperation) + cb.check() + + print("ok") + + sys.stdout.write("catching unknown local exception with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower.begin_throwLocalException(cb.response, cb.exception_LocalException) + cb.check() + + cb = Callback() + thrower.begin_throwLocalExceptionIdempotent(cb.response, cb.exception_LocalException) + cb.check() + + print("ok") + + sys.stdout.write("catching unknown non-Ice exception with AMI mapping... ") + sys.stdout.flush() + + cb = Callback() + thrower.begin_throwNonIceException(cb.response, cb.exception_NonIceException) + cb.check() + + print("ok") + + return thrower diff --git a/python/test/Ice/exceptions/Client.py b/python/test/Ice/exceptions/Client.py new file mode 100755 index 00000000000..3f535c2a2d7 --- /dev/null +++ b/python/test/Ice/exceptions/Client.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import AllTests + +def run(args, communicator): + thrower = AllTests.allTests(communicator) + thrower.shutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.MessageSizeMax", "10") + initData.properties.setProperty("Ice.Warn.Connections", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/exceptions/Collocated.py b/python/test/Ice/exceptions/Collocated.py new file mode 100755 index 00000000000..d60527a3d61 --- /dev/null +++ b/python/test/Ice/exceptions/Collocated.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI, AllTests + +def run(args, communicator): + properties = communicator.getProperties() + properties.setProperty("Ice.Warn.Dispatch", "0") + properties.setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI.ThrowerI() + adapter.add(object, communicator.stringToIdentity("thrower")) + #adapter.activate() // Don't activate OA to ensure collocation is used. + + thrower = AllTests.allTests(communicator) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.MessageSizeMax", "10") + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/exceptions/Server.py b/python/test/Ice/exceptions/Server.py new file mode 100755 index 00000000000..ba67f7b1f55 --- /dev/null +++ b/python/test/Ice/exceptions/Server.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI + +def run(args, communicator): + adapter = communicator.createObjectAdapter("TestAdapter") + adapter2 = communicator.createObjectAdapter("TestAdapter2") + adapter3 = communicator.createObjectAdapter("TestAdapter3") + object = TestI.ThrowerI() + adapter.add(object, communicator.stringToIdentity("thrower")) + adapter2.add(object, communicator.stringToIdentity("thrower")) + adapter3.add(object, communicator.stringToIdentity("thrower")) + adapter.activate() + adapter2.activate() + adapter3.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Dispatch", "0") + initData.properties.setProperty("Ice.Warn.Connections", "0"); + initData.properties.setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + initData.properties.setProperty("Ice.MessageSizeMax", "10") + initData.properties.setProperty("TestAdapter2.Endpoints", "default -p 12011") + initData.properties.setProperty("TestAdapter2.MessageSizeMax", "0") + initData.properties.setProperty("TestAdapter3.Endpoints", "default -p 12012") + initData.properties.setProperty("TestAdapter3.MessageSizeMax", "1") + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/exceptions/ServerAMD.py b/python/test/Ice/exceptions/ServerAMD.py new file mode 100755 index 00000000000..9dd180dec06 --- /dev/null +++ b/python/test/Ice/exceptions/ServerAMD.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, array + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" TestAMD.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class ThrowerI(Test.Thrower): + def shutdown_async(self, cb, current=None): + current.adapter.getCommunicator().shutdown() + cb.ice_response() + + def supportsUndeclaredExceptions_async(self, cb, current=None): + cb.ice_response(True) + + def supportsAssertException_async(self, cb, current=None): + cb.ice_response(False) + + def throwAasA_async(self, cb, a, current=None): + ex = Test.A() + ex.aMem = a + cb.ice_exception(ex) + + def throwAorDasAorD_async(self, cb, a, current=None): + if a > 0: + ex = Test.A() + ex.aMem = a + cb.ice_exception(ex) + else: + ex = Test.D() + ex.dMem = a + cb.ice_exception(ex) + + def throwBasA_async(self, cb, a, b, current=None): + ex = Test.B() + ex.aMem = a + ex.bMem = b + raise ex + #cb.ice_exception(ex) + + def throwCasA_async(self, cb, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + cb.ice_exception(ex) + + def throwBasB_async(self, cb, a, b, current=None): + ex = Test.B() + ex.aMem = a + ex.bMem = b + raise ex + #cb.ice_exception(ex) + + def throwCasB_async(self, cb, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + cb.ice_exception(ex) + + def throwCasC_async(self, cb, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + cb.ice_exception(ex) + + def throwModA_async(self, cb, a, a2, current=None): + ex = Test.Mod.A() + ex.aMem = a + ex.a2Mem = a2 + raise ex + + def throwUndeclaredA_async(self, cb, a, current=None): + ex = Test.A() + ex.aMem = a + cb.ice_exception(ex) + + def throwUndeclaredB_async(self, cb, a, b, current=None): + ex = Test.B() + ex.aMem = a + ex.bMem = b + raise ex + #cb.ice_exception(ex) + + def throwUndeclaredC_async(self, cb, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + cb.ice_exception(ex) + + def throwLocalException_async(self, cb, current=None): + cb.ice_exception(Ice.TimeoutException()) + + def throwNonIceException_async(self, cb, current=None): + # Python-specific: make sure the argument is validated. + try: + cb.ice_exception('foo') + test(False) + except TypeError: + pass + + cb.ice_exception(RuntimeError("12345")) + + def throwAssertException_async(self, cb, current=None): + raise RuntimeError("operation `throwAssertException' not supported") + + def throwMemoryLimitException_async(self, cb, seq, current=None): + cb.ice_response(bytearray(20 * 1024)) + + def throwLocalExceptionIdempotent_async(self, cb, current=None): + cb.ice_exception(Ice.TimeoutException()) + + def throwAfterResponse_async(self, cb, current=None): + cb.ice_response() + raise RuntimeError("12345") + + def throwAfterException_async(self, cb, current=None): + cb.ice_exception(Test.A()) + raise RuntimeError("12345") + +def run(args, communicator): + adapter = communicator.createObjectAdapter("TestAdapter") + adapter2 = communicator.createObjectAdapter("TestAdapter2") + adapter3 = communicator.createObjectAdapter("TestAdapter3") + object = ThrowerI() + adapter.add(object, communicator.stringToIdentity("thrower")) + adapter2.add(object, communicator.stringToIdentity("thrower")) + adapter3.add(object, communicator.stringToIdentity("thrower")) + adapter.activate() + adapter2.activate() + adapter3.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Dispatch", "0") + initData.properties.setProperty("Ice.Warn.Connections", "0"); + initData.properties.setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + initData.properties.setProperty("Ice.MessageSizeMax", "10") + initData.properties.setProperty("TestAdapter2.Endpoints", "default -p 12011") + initData.properties.setProperty("TestAdapter2.MessageSizeMax", "0") + initData.properties.setProperty("TestAdapter3.Endpoints", "default -p 12012") + initData.properties.setProperty("TestAdapter3.MessageSizeMax", "1") + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/exceptions/Test.ice b/python/test/Ice/exceptions/Test.ice new file mode 100644 index 00000000000..cb519fa50f4 --- /dev/null +++ b/python/test/Ice/exceptions/Test.ice @@ -0,0 +1,86 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Empty +{ +}; + +interface Thrower; + +exception A +{ + int aMem; +}; + +exception B extends A +{ + int bMem; +}; + +exception C extends B +{ + int cMem; +}; + +exception D +{ + int dMem; +}; + +module Mod +{ + exception A extends ::Test::A + { + int a2Mem; + }; +}; + +interface Thrower +{ + void shutdown(); + bool supportsUndeclaredExceptions(); + bool supportsAssertException(); + + void throwAasA(int a) throws A; + void throwAorDasAorD(int a) throws A, D; + void throwBasA(int a, int b) throws A; + void throwCasA(int a, int b, int c) throws A; + void throwBasB(int a, int b) throws B; + void throwCasB(int a, int b, int c) throws B; + void throwCasC(int a, int b, int c) throws C; + + void throwModA(int a, int a2) throws Mod::A; + + void throwUndeclaredA(int a); + void throwUndeclaredB(int a, int b); + void throwUndeclaredC(int a, int b, int c); + void throwLocalException(); + void throwNonIceException(); + void throwAssertException(); + Ice::ByteSeq throwMemoryLimitException(Ice::ByteSeq seq); + + idempotent void throwLocalExceptionIdempotent(); + + void throwAfterResponse(); + void throwAfterException() throws A; +}; + +interface WrongOperation +{ + void noSuchOperation(); +}; + +}; diff --git a/python/test/Ice/exceptions/TestAMD.ice b/python/test/Ice/exceptions/TestAMD.ice new file mode 100644 index 00000000000..6c6cd19342d --- /dev/null +++ b/python/test/Ice/exceptions/TestAMD.ice @@ -0,0 +1,81 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/BuiltinSequences.ice> + +module Test +{ + +interface Thrower; + +exception A +{ + int aMem; +}; + +exception B extends A +{ + int bMem; +}; + +exception C extends B +{ + int cMem; +}; + +exception D +{ + int dMem; +}; + +module Mod +{ + exception A extends ::Test::A + { + int a2Mem; + }; +}; + + +["amd"] interface Thrower +{ + void shutdown(); + bool supportsUndeclaredExceptions(); + bool supportsAssertException(); + + void throwAasA(int a) throws A; + void throwAorDasAorD(int a) throws A, D; + void throwBasA(int a, int b) throws A; + void throwCasA(int a, int b, int c) throws A; + void throwBasB(int a, int b) throws B; + void throwCasB(int a, int b, int c) throws B; + void throwCasC(int a, int b, int c) throws C; + + void throwModA(int a, int a2) throws Mod::A; + + void throwUndeclaredA(int a); + void throwUndeclaredB(int a, int b); + void throwUndeclaredC(int a, int b, int c); + void throwLocalException(); + void throwNonIceException(); + void throwAssertException(); + Ice::ByteSeq throwMemoryLimitException(Ice::ByteSeq seq); + + void throwAfterResponse(); + void throwAfterException() throws A; +}; + +["amd"] interface WrongOperation +{ + void noSuchOperation(); +}; + +}; diff --git a/python/test/Ice/exceptions/TestI.py b/python/test/Ice/exceptions/TestI.py new file mode 100644 index 00000000000..7ff371fc0b1 --- /dev/null +++ b/python/test/Ice/exceptions/TestI.py @@ -0,0 +1,108 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, array, sys + +class ThrowerI(Test.Thrower): + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def supportsUndeclaredExceptions(self, current=None): + return True + + def supportsAssertException(self, current=None): + return False + + def throwAasA(self, a, current=None): + ex = Test.A() + ex.aMem = a + raise ex + + def throwAorDasAorD(self, a, current=None): + if a > 0: + ex = Test.A() + ex.aMem = a + raise ex + else: + ex = Test.D() + ex.dMem = a + raise ex + + def throwBasA(self, a, b, current=None): + self.throwBasB(a, b, current) + + def throwCasA(self, a, b, c, current=None): + self.throwCasC(a, b, c, current) + + def throwBasB(self, a, b, current=None): + ex = Test.B() + ex.aMem = a + ex.bMem = b + raise ex + + def throwCasB(self, a, b, c, current=None): + self.throwCasC(a, b, c, current) + + def throwCasC(self, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + raise ex + + def throwModA(self, a, a2, current=None): + ex = Test.Mod.A() + ex.aMem = a + ex.a2Mem = a2 + raise ex + + def throwUndeclaredA(self, a, current=None): + ex = Test.A() + ex.aMem = a + raise ex + + def throwUndeclaredB(self, a, b, current=None): + ex = Test.B() + ex.aMem = a + ex.bMem = b + raise ex + + def throwUndeclaredC(self, a, b, c, current=None): + ex = Test.C() + ex.aMem = a + ex.bMem = b + ex.cMem = c + raise ex + + def throwLocalException(self, current=None): + raise Ice.TimeoutException() + + def throwNonIceException(self, current=None): + raise RuntimeError("12345") + + def throwAssertException(self, current=None): + raise RuntimeError("operation `throwAssertException' not supported") + + def throwMemoryLimitException(self, seq, current=None): + return bytearray(20 * 1024) + + def throwLocalExceptionIdempotent(self, current=None): + raise Ice.TimeoutException() + + def throwAfterResponse(self, current=None): + # + # Only relevant for AMD. + # + pass + + def throwAfterException(self, current=None): + # + # Only relevant for AMD. + # + raise Test.A() diff --git a/python/test/Ice/exceptions/run.py b/python/test/Ice/exceptions/run.py new file mode 100755 index 00000000000..9445951eca9 --- /dev/null +++ b/python/test/Ice/exceptions/run.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with compact (default) format.") +TestUtil.clientServerTest() + +print("Running test with sliced format.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat", + additionalServerOptions="--Ice.Default.SlicedFormat") + +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running test with compact (default) format and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") + +print("Running test with sliced format and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py", + additionalClientOptions="--Ice.Default.SlicedFormat", + additionalServerOptions="--Ice.Default.SlicedFormat") + +print("Running test with 1.0 encoding and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py", + additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running collocated test.") +TestUtil.collocatedTest() diff --git a/python/test/Ice/facets/AllTests.py b/python/test/Ice/facets/AllTests.py new file mode 100644 index 00000000000..b1059672d21 --- /dev/null +++ b/python/test/Ice/facets/AllTests.py @@ -0,0 +1,183 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class EmptyI(Test.Empty): + pass + +def allTests(communicator): + + sys.stdout.write("testing Ice.Admin.Facets property... ") + sys.stdout.flush() + test(len(communicator.getProperties().getPropertyAsList("Ice.Admin.Facets")) == 0) + communicator.getProperties().setProperty("Ice.Admin.Facets", "foobar"); + facetFilter = communicator.getProperties().getPropertyAsList("Ice.Admin.Facets"); + test(len(facetFilter) == 1 and facetFilter[0] == "foobar"); + communicator.getProperties().setProperty("Ice.Admin.Facets", "foo\\'bar"); + facetFilter = communicator.getProperties().getPropertyAsList("Ice.Admin.Facets"); + test(len(facetFilter) == 1 and facetFilter[0] == "foo'bar"); + communicator.getProperties().setProperty("Ice.Admin.Facets", "'foo bar' toto 'titi'"); + facetFilter = communicator.getProperties().getPropertyAsList("Ice.Admin.Facets"); + test(len(facetFilter) == 3 and facetFilter[0] == "foo bar" and facetFilter[1] == "toto" + and facetFilter[2] == "titi"); + communicator.getProperties().setProperty("Ice.Admin.Facets", "'foo bar\\' toto' 'titi'"); + facetFilter = communicator.getProperties().getPropertyAsList("Ice.Admin.Facets"); + test(len(facetFilter) == 2 and facetFilter[0] == "foo bar' toto" and facetFilter[1] == "titi"); + # communicator.getProperties().setProperty("Ice.Admin.Facets", "'foo bar' 'toto titi"); + # facetFilter = communicator.getProperties().getPropertyAsList("Ice.Admin.Facets"); + # test(len(facetFilter) == 0); + communicator.getProperties().setProperty("Ice.Admin.Facets", ""); + print("ok") + + sys.stdout.write("testing facet registration exceptions... ") + sys.stdout.flush() + communicator.getProperties().setProperty("FacetExceptionTestAdapter.Endpoints", "default") + adapter = communicator.createObjectAdapter("FacetExceptionTestAdapter") + obj = EmptyI() + adapter.add(obj, communicator.stringToIdentity("d")) + adapter.addFacet(obj, communicator.stringToIdentity("d"), "facetABCD") + try: + adapter.addFacet(obj, communicator.stringToIdentity("d"), "facetABCD") + test(false) + except Ice.AlreadyRegisteredException: + pass + adapter.removeFacet(communicator.stringToIdentity("d"), "facetABCD") + try: + adapter.removeFacet(communicator.stringToIdentity("d"), "facetABCD") + test(false) + except Ice.NotRegisteredException: + pass + print("ok") + + sys.stdout.write("testing removeAllFacets... ") + sys.stdout.flush() + obj1 = EmptyI() + obj2 = EmptyI() + adapter.addFacet(obj1, communicator.stringToIdentity("id1"), "f1") + adapter.addFacet(obj2, communicator.stringToIdentity("id1"), "f2") + obj3 = EmptyI() + adapter.addFacet(obj1, communicator.stringToIdentity("id2"), "f1") + adapter.addFacet(obj2, communicator.stringToIdentity("id2"), "f2") + adapter.addFacet(obj3, communicator.stringToIdentity("id2"), "") + fm = adapter.removeAllFacets(communicator.stringToIdentity("id1")) + test(len(fm) == 2) + test(fm["f1"] == obj1) + test(fm["f2"] == obj2) + try: + adapter.removeAllFacets(communicator.stringToIdentity("id1")) + test(false) + except Ice.NotRegisteredException: + pass + fm = adapter.removeAllFacets(communicator.stringToIdentity("id2")) + test(len(fm) == 3) + test(fm["f1"] == obj1) + test(fm["f2"] == obj2) + test(fm[""] == obj3) + print("ok") + + adapter.deactivate() + + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "d:default -p 12010" + db = communicator.stringToProxy(ref) + test(db) + print("ok") + + sys.stdout.write("testing unchecked cast... ") + sys.stdout.flush() + obj = Ice.ObjectPrx.uncheckedCast(db) + test(obj.ice_getFacet() == "") + obj = Ice.ObjectPrx.uncheckedCast(db, "facetABCD") + test(obj.ice_getFacet() == "facetABCD") + obj2 = Ice.ObjectPrx.uncheckedCast(obj) + test(obj2.ice_getFacet() == "facetABCD") + obj3 = Ice.ObjectPrx.uncheckedCast(obj, "") + test(obj3.ice_getFacet() == "") + d = Test.DPrx.uncheckedCast(db) + test(d.ice_getFacet() == "") + df = Test.DPrx.uncheckedCast(db, "facetABCD") + test(df.ice_getFacet() == "facetABCD") + df2 = Test.DPrx.uncheckedCast(df) + test(df2.ice_getFacet() == "facetABCD") + df3 = Test.DPrx.uncheckedCast(df, "") + test(df3.ice_getFacet() == "") + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + obj = Ice.ObjectPrx.checkedCast(db) + test(obj.ice_getFacet() == "") + obj = Ice.ObjectPrx.checkedCast(db, "facetABCD") + test(obj.ice_getFacet() == "facetABCD") + obj2 = Ice.ObjectPrx.checkedCast(obj) + test(obj2.ice_getFacet() == "facetABCD") + obj3 = Ice.ObjectPrx.checkedCast(obj, "") + test(obj3.ice_getFacet() == "") + d = Test.DPrx.checkedCast(db) + test(d.ice_getFacet() == "") + df = Test.DPrx.checkedCast(db, "facetABCD") + test(df.ice_getFacet() == "facetABCD") + df2 = Test.DPrx.checkedCast(df) + test(df2.ice_getFacet() == "facetABCD") + df3 = Test.DPrx.checkedCast(df, "") + test(df3.ice_getFacet() == "") + test(Test.DPrx.checkedCast(df, "bogus") == None) + print("ok") + + sys.stdout.write("testing non-facets A, B, C, and D... ") + sys.stdout.flush() + d = Test.DPrx.checkedCast(db) + test(d) + test(d == db) + test(d.callA() == "A") + test(d.callB() == "B") + test(d.callC() == "C") + test(d.callD() == "D") + print("ok") + + sys.stdout.write("testing facets A, B, C, and D... ") + sys.stdout.flush() + df = Test.DPrx.checkedCast(d, "facetABCD") + test(df) + test(df.callA() == "A") + test(df.callB() == "B") + test(df.callC() == "C") + test(df.callD() == "D") + print("ok") + + sys.stdout.write("testing facets E and F... ") + sys.stdout.flush() + ff = Test.FPrx.checkedCast(d, "facetEF") + test(ff) + test(ff.callE() == "E") + test(ff.callF() == "F") + print("ok") + + sys.stdout.write("testing facet G... ") + sys.stdout.flush() + gf = Test.GPrx.checkedCast(ff, "facetGH") + test(gf) + test(gf.callG() == "G") + print("ok") + + sys.stdout.write("testing whether casting preserves the facet... ") + sys.stdout.flush() + hf = Test.HPrx.checkedCast(gf) + test(hf) + test(hf.callG() == "G") + test(hf.callH() == "H") + print("ok") + + return gf diff --git a/python/test/Ice/facets/Client.py b/python/test/Ice/facets/Client.py new file mode 100755 index 00000000000..7b008b0ad8f --- /dev/null +++ b/python/test/Ice/facets/Client.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice + +Ice.loadSlice('Test.ice') +import AllTests + +def run(args, communicator): + g = AllTests.allTests(communicator) + g.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/facets/Collocated.py b/python/test/Ice/facets/Collocated.py new file mode 100755 index 00000000000..8fbc45a0f31 --- /dev/null +++ b/python/test/Ice/facets/Collocated.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + d = TestI.DI() + adapter.add(d, communicator.stringToIdentity("d")) + adapter.addFacet(d, communicator.stringToIdentity("d"), "facetABCD") + f = TestI.FI() + adapter.addFacet(f, communicator.stringToIdentity("d"), "facetEF") + h = TestI.HI(communicator) + adapter.addFacet(h, communicator.stringToIdentity("d"), "facetGH") + + #adapter.activate() // Don't activate OA to ensure collocation is used. + + AllTests.allTests(communicator) + + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/facets/Server.py b/python/test/Ice/facets/Server.py new file mode 100755 index 00000000000..96145347213 --- /dev/null +++ b/python/test/Ice/facets/Server.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + d = TestI.DI() + adapter.add(d, communicator.stringToIdentity("d")) + adapter.addFacet(d, communicator.stringToIdentity("d"), "facetABCD") + f = TestI.FI() + adapter.addFacet(f, communicator.stringToIdentity("d"), "facetEF") + h = TestI.HI(communicator) + adapter.addFacet(h, communicator.stringToIdentity("d"), "facetGH") + + adapter.activate() + communicator.waitForShutdown() + + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/facets/Test.ice b/python/test/Ice/facets/Test.ice new file mode 100644 index 00000000000..d73c6594829 --- /dev/null +++ b/python/test/Ice/facets/Test.ice @@ -0,0 +1,60 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface Empty +{ +}; + +interface A +{ + string callA(); +}; + +interface B extends A +{ + string callB(); +}; + +interface C extends A +{ + string callC(); +}; + +interface D extends B, C +{ + string callD(); +}; + +interface E +{ + string callE(); +}; + +interface F extends E +{ + string callF(); +}; + +interface G +{ + void shutdown(); + string callG(); +}; + +interface H extends G +{ + string callH(); +}; + +}; diff --git a/python/test/Ice/facets/TestI.py b/python/test/Ice/facets/TestI.py new file mode 100644 index 00000000000..9f709245554 --- /dev/null +++ b/python/test/Ice/facets/TestI.py @@ -0,0 +1,51 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Test + +class AI(Test.A): + def callA(self, current=None): + return "A" + +class BI(Test.B, AI): + def callB(self, current=None): + return "B" + +class CI(Test.C, AI): + def callC(self, current=None): + return "C" + +class DI(Test.D, BI, CI): + def callD(self, current=None): + return "D" + +class EI(Test.E): + def callE(self, current=None): + return "E" + +class FI(Test.F, EI): + def callF(self, current=None): + return "F" + +class GI(Test.G): + def __init__(self, communicator): + self._communicator = communicator + + def shutdown(self, current=None): + self._communicator.shutdown() + + def callG(self, current=None): + return "G" + +class HI(Test.H, GI): + def __init__(self, communicator): + GI.__init__(self, communicator) + + def callH(self, current=None): + return "H" diff --git a/python/test/Ice/facets/run.py b/python/test/Ice/facets/run.py new file mode 100755 index 00000000000..9487c74a4f5 --- /dev/null +++ b/python/test/Ice/facets/run.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() +TestUtil.collocatedTest() diff --git a/python/test/Ice/faultTolerance/AllTests.py b/python/test/Ice/faultTolerance/AllTests.py new file mode 100644 index 00000000000..04f78961b24 --- /dev/null +++ b/python/test/Ice/faultTolerance/AllTests.py @@ -0,0 +1,175 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, sys, threading + +Ice.loadSlice('Test.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def response(self): + test(False) + + def exception(self, ex): + test(False) + + def opPidI(self, pid): + self._pid = pid + self.called() + + def opShutdownI(self): + self.called() + + def exceptAbortI(self, ex): + try: + raise ex + except Ice.ConnectionLostException: + pass + except Ice.ConnectFailedException: + pass + except Ice.Exception as ex: + print(ex) + test(False) + self.called() + + def pid(self): + return self._pid + +def allTests(communicator, ports): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "test" + for p in ports: + ref = ref + ":default -p " + str(p) + base = communicator.stringToProxy(ref) + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + obj = Test.TestIntfPrx.checkedCast(base) + test(obj) + test(obj == base) + print("ok") + + oldPid = 0 + ami = False + i = 1 + j = 0 + while i <= len(ports): + if j > 3: + j = 0 + ami = not ami + + if not ami: + sys.stdout.write("testing server #%d... " % i) + sys.stdout.flush() + pid = obj.pid() + test(pid != oldPid) + print("ok") + oldPid = pid + else: + sys.stdout.write("testing server #%d with AMI... " % i) + sys.stdout.flush() + cb = Callback() + obj.begin_pid(cb.opPidI, cb.exception) + cb.check() + pid = cb.pid() + test(pid != oldPid) + print("ok") + oldPid = pid + + if j == 0: + if not ami: + sys.stdout.write("shutting down server #%d... " % i) + sys.stdout.flush() + obj.shutdown() + print("ok") + else: + sys.stdout.write("shutting down server #%d with AMI... " % i) + sys.stdout.flush() + cb = Callback() + obj.begin_shutdown(cb.opShutdownI, cb.exception) + cb.check() + print("ok") + elif j == 1 or i + 1 > len(ports): + if not ami: + sys.stdout.write("aborting server #%d... " % i) + sys.stdout.flush() + try: + obj.abort() + test(False) + except Ice.ConnectionLostException: + print("ok") + except Ice.ConnectFailedException: + print("ok") + else: + sys.stdout.write("aborting server #%d with AMI... " % i) + sys.stdout.flush() + cb = Callback() + obj.begin_abort(cb.response, cb.exceptAbortI) + cb.check() + print("ok") + elif j == 2 or j == 3: + if not ami: + sys.stdout.write("aborting server #%d and #%d with idempotent call... " % (i, i + 1)) + sys.stdout.flush() + try: + obj.idempotentAbort() + test(False) + except Ice.ConnectionLostException: + print("ok") + except Ice.ConnectFailedException: + print("ok") + else: + sys.stdout.write("aborting server #%d and #%d with idempotent AMI call... " % (i, i + 1)) + sys.stdout.flush() + cb = Callback() + obj.begin_idempotentAbort(cb.response, cb.exceptAbortI) + cb.check() + print("ok") + + i = i + 1 + else: + assert(False) + + i = i + 1 + j = j + 1 + + sys.stdout.write("testing whether all servers are gone... ") + sys.stdout.flush() + try: + obj.ice_ping() + test(False) + except Ice.LocalException: + print("ok") diff --git a/python/test/Ice/faultTolerance/Client.py b/python/test/Ice/faultTolerance/Client.py new file mode 100755 index 00000000000..9fcd238c561 --- /dev/null +++ b/python/test/Ice/faultTolerance/Client.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice, AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def usage(n): + sys.stderr.write("Usage: " + n + " port...\n") + +def run(args, communicator): + ports = [] + for arg in args[1:]: + if arg[0] == '-': + sys.stderr.write(args[0] + ": unknown option `" + arg + "'\n") + usage(args[0]) + return False + + ports.append(int(arg)) + + if len(ports) == 0: + sys.stderr.write(args[0] + ": no ports specified\n") + usage(args[0]) + return False + + try: + AllTests.allTests(communicator, ports) + except: + traceback.print_exc() + test(False) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + + # + # This test aborts servers, so we don't want warnings. + # + initData.properties.setProperty('Ice.Warn.Connections', '0') + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/faultTolerance/Server.py b/python/test/Ice/faultTolerance/Server.py new file mode 100755 index 00000000000..3bf4b269367 --- /dev/null +++ b/python/test/Ice/faultTolerance/Server.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test + +def usage(n): + sys.stderr.write("Usage: " + n + " port\n") + +class TestI(Test.TestIntf): + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def abort(self, current=None): + sys.stdout.write("aborting...") + os._exit(0) + + def idempotentAbort(self, current=None): + os._exit(0) + + def pid(self, current=None): + return os.getpid() + +def run(args, communicator): + port = 0 + for arg in args[1:]: + if arg[0] == '-': + sys.stderr.write(args[0] + ": unknown option `" + arg + "'\n") + usage(args[0]) + return False + if port > 0: + sys.stderr.write(args[0] + ": only one port can be specified\n") + usage(args[0]) + return False + + port = int(arg) + + if port <= 0: + sys.stderr.write(args[0] + ": no port specified\n") + usage(args[0]) + return False + + endpts = "default -p " + str(port) + ":udp" + communicator.getProperties().setProperty("TestAdapter.Endpoints", endpts) + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI() + adapter.add(object, communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + # + # In this test, we need a longer server idle time, otherwise + # our test servers may time out before they are used in the + # test. + # + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.ServerIdleTime", "120") # Two minutes. + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/faultTolerance/Test.ice b/python/test/Ice/faultTolerance/Test.ice new file mode 100644 index 00000000000..d5488ad5726 --- /dev/null +++ b/python/test/Ice/faultTolerance/Test.ice @@ -0,0 +1,23 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +interface TestIntf +{ + void shutdown(); + void abort(); + idempotent void idempotentAbort(); + idempotent int pid(); +}; + +}; diff --git a/python/test/Ice/faultTolerance/run.py b/python/test/Ice/faultTolerance/run.py new file mode 100755 index 00000000000..d3db12b4e2f --- /dev/null +++ b/python/test/Ice/faultTolerance/run.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +server = os.path.join(os.getcwd(), "Server.py") +client = os.path.join(os.getcwd(), "Client.py") + +num = 12 +base = 12340 + +serverProc = [] +for i in range(0, num): + sys.stdout.write("starting server #%d... " % (i + 1)) + sys.stdout.flush() + serverProc.append(TestUtil.startServer(server, "%d" % (base + i))) + print("ok") + +ports = "" +for i in range(0, num): + ports = "%s %d" % (ports, base + i) +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient(client, ports, startReader = False) +print("ok") +clientProc.startReader() + +clientProc.waitTestSuccess() +for p in serverProc: + p.waitTestSuccess() diff --git a/python/test/Ice/info/AllTests.py b/python/test/Ice/info/AllTests.py new file mode 100644 index 00000000000..c8c754e804b --- /dev/null +++ b/python/test/Ice/info/AllTests.py @@ -0,0 +1,175 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + sys.stdout.write("testing proxy endpoint information... ") + sys.stdout.flush() + + p1 = communicator.stringToProxy("test -t:default -h tcphost -p 10000 -t 1200 -z --sourceAddress 10.10.10.10:" + \ + "udp -h udphost -p 10001 --interface eth0 --ttl 5 --sourceAddress 10.10.10.10:" + \ + "opaque -e 1.8 -t 100 -v ABCD") + + endps = p1.ice_getEndpoints() + + ipEndpoint = endps[0].getInfo() + test(isinstance(ipEndpoint, Ice.IPEndpointInfo)) + test(ipEndpoint.host == "tcphost") + test(ipEndpoint.port == 10000) + test(ipEndpoint.sourceAddress == "10.10.10.10") + test(ipEndpoint.timeout == 1200) + test(ipEndpoint.compress) + test(not ipEndpoint.datagram()) + test((ipEndpoint.type() == Ice.TCPEndpointType and not ipEndpoint.secure()) or + (ipEndpoint.type() == Ice.SSLEndpointType and ipEndpoint.secure()) or # SSL + (ipEndpoint.type() == Ice.WSEndpointType and not ipEndpoint.secure()) or # WS + (ipEndpoint.type() == Ice.WSSEndpointType and ipEndpoint.secure())) # WS + test((ipEndpoint.type() == Ice.TCPEndpointType and isinstance(ipEndpoint, Ice.TCPEndpointInfo)) or + (ipEndpoint.type() == Ice.SSLEndpointType) or + (ipEndpoint.type() == Ice.WSEndpointType and isinstance(ipEndpoint, Ice.WSEndpointInfo)) or + (ipEndpoint.type() == Ice.WSSEndpointType and isinstance(ipEndpoint, Ice.WSEndpointInfo))) + + udpEndpoint = endps[1].getInfo() + test(isinstance(udpEndpoint, Ice.UDPEndpointInfo)) + test(udpEndpoint.host == "udphost") + test(udpEndpoint.port == 10001) + test(udpEndpoint.sourceAddress == "10.10.10.10") + test(udpEndpoint.mcastInterface == "eth0") + test(udpEndpoint.mcastTtl == 5) + test(udpEndpoint.timeout == -1) + test(not udpEndpoint.compress) + test(not udpEndpoint.secure()) + test(udpEndpoint.datagram()) + test(udpEndpoint.type() == Ice.UDPEndpointType) + + opaqueEndpoint = endps[2].getInfo() + test(isinstance(opaqueEndpoint, Ice.OpaqueEndpointInfo)) + test(opaqueEndpoint.rawEncoding == Ice.EncodingVersion(1, 8)) + + print("ok") + + defaultHost = communicator.getProperties().getProperty("Ice.Default.Host") + + sys.stdout.write("test object adapter endpoint information... ") + sys.stdout.flush() + + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -t 15000:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + endpoints = adapter.getEndpoints() + test(len(endpoints) == 2) + publishedEndpoints = adapter.getPublishedEndpoints() + test(endpoints == publishedEndpoints) + + ipEndpoint = endpoints[0].getInfo() + test(ipEndpoint.type() == Ice.TCPEndpointType or ipEndpoint.type() == 2 or ipEndpoint.type() == 4 or + ipEndpoint.type() == 5) + test(ipEndpoint.host == defaultHost) + test(ipEndpoint.port > 0) + test(ipEndpoint.timeout == 15000) + + udpEndpoint = endpoints[1].getInfo() + test(udpEndpoint.host == defaultHost) + test(udpEndpoint.datagram()) + test(udpEndpoint.port > 0) + + adapter.destroy() + + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -h * -p 12020") + communicator.getProperties().setProperty("TestAdapter.PublishedEndpoints", "default -h 127.0.0.1 -p 12020") + adapter = communicator.createObjectAdapter("TestAdapter") + + endpoints = adapter.getEndpoints() + test(len(endpoints) >= 1) + publishedEndpoints = adapter.getPublishedEndpoints() + test(len(publishedEndpoints) == 1) + + for i in range(0, len(endpoints)): + ipEndpoint = endpoints[i].getInfo() + test(ipEndpoint.port == 12020) + + ipEndpoint = publishedEndpoints[0].getInfo() + test(ipEndpoint.host == "127.0.0.1") + test(ipEndpoint.port == 12020) + + adapter.destroy() + + print("ok") + + base = communicator.stringToProxy("test:default -p 12010:udp -p 12010") + testIntf = Test.TestIntfPrx.checkedCast(base) + + sys.stdout.write("test connection endpoint information... ") + sys.stdout.flush() + + ipinfo = base.ice_getConnection().getEndpoint().getInfo() + test(ipinfo.port == 12010) + test(not ipinfo.compress) + test(ipinfo.host == defaultHost) + + ctx = testIntf.getEndpointInfoAsContext() + test(ctx["host"] == ipinfo.host) + test(ctx["compress"] == "false") + port = int(ctx["port"]) + test(port > 0) + + udp = base.ice_datagram().ice_getConnection().getEndpoint().getInfo() + test(udp.port == 12010) + test(udp.host == defaultHost) + + print("ok") + + sys.stdout.write("testing connection information... ") + sys.stdout.flush() + + connection = base.ice_getConnection() + connection.setBufferSize(1024, 2048) + + info = connection.getInfo() + test(not info.incoming) + test(len(info.adapterName) == 0) + test(info.remotePort == 12010) + if defaultHost == '127.0.0.1': + test(info.remoteAddress == defaultHost) + test(info.localAddress == defaultHost) + test(info.rcvSize >= 1024) + test(info.sndSize >= 2048) + + ctx = testIntf.getConnectionInfoAsContext() + test(ctx["incoming"] == "true") + test(ctx["adapterName"] == "TestAdapter") + test(ctx["remoteAddress"] == info.localAddress) + test(ctx["localAddress"] == info.remoteAddress) + test(ctx["remotePort"] == str(info.localPort)) + test(ctx["localPort"] == str(info.remotePort)) + + if(base.ice_getConnection().type() == "ws" or base.ice_getConnection().type() == "wss"): + test(isinstance(info, Ice.WSConnectionInfo)) + + test(info.headers["Upgrade"] == "websocket") + test(info.headers["Connection"] == "Upgrade") + test(info.headers["Sec-WebSocket-Protocol"] == "ice.zeroc.com") + test("Sec-WebSocket-Accept" in info.headers); + + test(ctx["ws.Upgrade"] == "websocket") + test(ctx["ws.Connection"] == "Upgrade") + test(ctx["ws.Sec-WebSocket-Protocol"] == "ice.zeroc.com") + test(ctx["ws.Sec-WebSocket-Version"] == "13") + test("ws.Sec-WebSocket-Key" in ctx) + + print("ok") + + testIntf.shutdown() + + communicator.shutdown() + communicator.waitForShutdown() diff --git a/python/test/Ice/info/Client.py b/python/test/Ice/info/Client.py new file mode 100755 index 00000000000..cb71229d9da --- /dev/null +++ b/python/test/Ice/info/Client.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + AllTests.allTests(communicator) + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/info/Server.py b/python/test/Ice/info/Server.py new file mode 100755 index 00000000000..e4d7ccf824f --- /dev/null +++ b/python/test/Ice/info/Server.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TestI.MyDerivedClassI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/info/Test.ice b/python/test/Ice/info/Test.ice new file mode 100644 index 00000000000..a71990ba3db --- /dev/null +++ b/python/test/Ice/info/Test.ice @@ -0,0 +1,26 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +interface TestIntf +{ + void shutdown(); + + Ice::Context getEndpointInfoAsContext(); + + Ice::Context getConnectionInfoAsContext(); +}; + +}; diff --git a/python/test/Ice/info/TestI.py b/python/test/Ice/info/TestI.py new file mode 100644 index 00000000000..c0b266a7ba4 --- /dev/null +++ b/python/test/Ice/info/TestI.py @@ -0,0 +1,69 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test +import time + +class MyDerivedClassI(Test.TestIntf): + def __init__(self): + self.ctx = None + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def getEndpointInfoAsContext(self, current): + ctx = {} + info = current.con.getEndpoint().getInfo() + ctx["timeout"] = str(info.timeout) + if info.compress: + ctx["compress"] = "true" + else: + ctx["compress"] ="false" + if info.datagram(): + ctx["datagram"] = "true" + else: + ctx["datagram"] ="false" + if info.secure(): + ctx["secure"] = "true" + else: + ctx["secure"] ="false" + ctx["type"] = str(info.type()) + + ctx["host"] = info.host + ctx["port"] = str(info.port) + + if isinstance(info, Ice.UDPEndpointInfo): + ctx["protocolMajor"] = str(info.protocolMajor) + ctx["protocolMinor"] = str(info.protocolMinor) + ctx["encodingMajor"] = str(info.encodingMajor) + ctx["encodingMinor"] = str(info.encodingMinor) + ctx["mcastInterface"] = info.mcastInterface + ctx["mcastTtl"] = str(info.mcastTtl) + + return ctx + + def getConnectionInfoAsContext(self, current): + ctx = {} + info = current.con.getInfo() + ctx["adapterName"] = info.adapterName + if info.incoming: + ctx["incoming"] = "true" + else: + ctx["incoming"] ="false" + + ctx["localAddress"] = info.localAddress + ctx["localPort"] = str(info.localPort) + ctx["remoteAddress"] = info.remoteAddress + ctx["remotePort"] = str(info.remotePort) + + if isinstance(info, Ice.WSConnectionInfo): + for key, value in info.headers.items(): + ctx["ws." + key] = value + + return ctx diff --git a/python/test/Ice/info/run.py b/python/test/Ice/info/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/info/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/inheritance/AllTests.py b/python/test/Ice/inheritance/AllTests.py new file mode 100644 index 00000000000..67922a33ff5 --- /dev/null +++ b/python/test/Ice/inheritance/AllTests.py @@ -0,0 +1,216 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "initial:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + initial = Test.InitialPrx.checkedCast(base) + test(initial) + test(initial == base) + print("ok") + + sys.stdout.write("getting proxies for class hierarchy... ") + sys.stdout.flush() + ca = initial.caop() + cb = initial.cbop() + cc = initial.ccop() + cd = initial.cdop() + test(ca != cb) + test(ca != cc) + test(ca != cd) + test(cb != cc) + test(cb != cd) + test(cc != cd) + print("ok") + + sys.stdout.write("getting proxies for interface hierarchy... ") + sys.stdout.flush() + ia = initial.iaop() + ib1 = initial.ib1op() + ib2 = initial.ib2op() + ic = initial.icop() + test(ia != ib1) + test(ia != ib2) + test(ia != ic) + test(ib1 != ic) + test(ib2 != ic) + print("ok") + + sys.stdout.write("invoking proxy operations on class hierarchy... ") + sys.stdout.flush() + cao = ca.caop(ca) + test(cao == ca) + cao = ca.caop(cb) + test(cao == cb) + cao = ca.caop(cc) + test(cao == cc) + cao = cb.caop(ca) + test(cao == ca) + cao = cb.caop(cb) + test(cao == cb) + cao = cb.caop(cc) + test(cao == cc) + cao = cc.caop(ca) + test(cao == ca) + cao = cc.caop(cb) + test(cao == cb) + cao = cc.caop(cc) + test(cao == cc) + + cao = cb.cbop(cb) + test(cao == cb) + cbo = cb.cbop(cb) + test(cbo == cb) + cao = cb.cbop(cc) + test(cao == cc) + cbo = cb.cbop(cc) + test(cbo == cc) + cao = cc.cbop(cb) + test(cao == cb) + cbo = cc.cbop(cb) + test(cbo == cb) + cao = cc.cbop(cc) + test(cao == cc) + cbo = cc.cbop(cc) + test(cbo == cc) + + cao = cc.ccop(cc) + test(cao == cc) + cbo = cc.ccop(cc) + test(cbo == cc) + cco = cc.ccop(cc) + test(cco == cc) + print("ok") + + sys.stdout.write("ditto, but for interface hierarchy... ") + sys.stdout.flush() + iao = ia.iaop(ia) + test(iao == ia) + iao = ia.iaop(ib1) + test(iao == ib1) + iao = ia.iaop(ib2) + test(iao == ib2) + iao = ia.iaop(ic) + test(iao == ic) + iao = ib1.iaop(ia) + test(iao == ia) + iao = ib1.iaop(ib1) + test(iao == ib1) + iao = ib1.iaop(ib2) + test(iao == ib2) + iao = ib1.iaop(ic) + test(iao == ic) + iao = ib2.iaop(ia) + test(iao == ia) + iao = ib2.iaop(ib1) + test(iao == ib1) + iao = ib2.iaop(ib2) + test(iao == ib2) + iao = ib2.iaop(ic) + test(iao == ic) + iao = ic.iaop(ia) + test(iao == ia) + iao = ic.iaop(ib1) + test(iao == ib1) + iao = ic.iaop(ib2) + test(iao == ib2) + iao = ic.iaop(ic) + test(iao == ic) + + iao = ib1.ib1op(ib1) + test(iao == ib1) + ib1o = ib1.ib1op(ib1) + test(ib1o == ib1) + iao = ib1.ib1op(ic) + test(iao == ic) + ib1o = ib1.ib1op(ic) + test(ib1o == ic) + iao = ic.ib1op(ib1) + test(iao == ib1) + ib1o = ic.ib1op(ib1) + test(ib1o == ib1) + iao = ic.ib1op(ic) + test(iao == ic) + ib1o = ic.ib1op(ic) + test(ib1o == ic) + + iao = ib2.ib2op(ib2) + test(iao == ib2) + ib2o = ib2.ib2op(ib2) + test(ib2o == ib2) + iao = ib2.ib2op(ic) + test(iao == ic) + ib2o = ib2.ib2op(ic) + test(ib2o == ic) + iao = ic.ib2op(ib2) + test(iao == ib2) + ib2o = ic.ib2op(ib2) + test(ib2o == ib2) + iao = ic.ib2op(ic) + test(iao == ic) + ib2o = ic.ib2op(ic) + test(ib2o == ic) + + iao = ic.icop(ic) + test(iao == ic) + ib1o = ic.icop(ic) + test(ib1o == ic) + ib2o = ic.icop(ic) + test(ib2o == ic) + ico = ic.icop(ic) + test(ico == ic) + + print("ok") + + sys.stdout.write("ditto, but for class implementing interfaces... ") + sys.stdout.flush() + cao = cd.caop(cd) + test(cao == cd) + cbo = cd.cbop(cd) + test(cbo == cd) + cco = cd.ccop(cd) + test(cco == cd) + + iao = cd.iaop(cd) + test(iao == cd) + ib1o = cd.ib1op(cd) + test(ib1o == cd) + ib2o = cd.ib2op(cd) + test(ib2o == cd) + + cao = cd.cdop(cd) + test(cao == cd) + cbo = cd.cdop(cd) + test(cbo == cd) + cco = cd.cdop(cd) + test(cco == cd) + + iao = cd.cdop(cd) + test(iao == cd) + ib1o = cd.cdop(cd) + test(ib1o == cd) + ib2o = cd.cdop(cd) + test(ib2o == cd) + + print("ok") + + return initial diff --git a/python/test/Ice/inheritance/Client.py b/python/test/Ice/inheritance/Client.py new file mode 100755 index 00000000000..d3f92a4e4ed --- /dev/null +++ b/python/test/Ice/inheritance/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import AllTests + +def run(args, communicator): + initial = AllTests.allTests(communicator) + initial.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/inheritance/Collocated.py b/python/test/Ice/inheritance/Collocated.py new file mode 100755 index 00000000000..0652f4d9169 --- /dev/null +++ b/python/test/Ice/inheritance/Collocated.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI.InitialI(adapter) + adapter.add(object, communicator.stringToIdentity("initial")) + #adapter.activate() // Don't activate OA to ensure collocation is used. + + AllTests.allTests(communicator) + + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/inheritance/Server.py b/python/test/Ice/inheritance/Server.py new file mode 100755 index 00000000000..381c8e36ba4 --- /dev/null +++ b/python/test/Ice/inheritance/Server.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI.InitialI(adapter) + adapter.add(object, communicator.stringToIdentity("initial")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/inheritance/Test.ice b/python/test/Ice/inheritance/Test.ice new file mode 100644 index 00000000000..7dd63ee98b6 --- /dev/null +++ b/python/test/Ice/inheritance/Test.ice @@ -0,0 +1,83 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +module MA +{ + +interface IA +{ + IA* iaop(IA* p); +}; + +class CA +{ + CA* caop(CA* p); +}; + +}; + +module MB +{ + +interface IB1 extends MA::IA +{ + IB1* ib1op(IB1* p); +}; + +interface IB2 extends MA::IA +{ + IB2* ib2op(IB2* p); +}; + +class CB extends MA::CA +{ + CB* cbop(CB* p); +}; + +}; + +module MA +{ + +interface IC extends MB::IB1, MB::IB2 +{ + IC* icop(IC* p); +}; + +class CC extends MB::CB +{ + CC* ccop(CC* p); +}; + +class CD extends CC implements MB::IB1, MB::IB2 +{ + CD* cdop(CD* p); +}; + +}; + +interface Initial +{ + void shutdown(); + MA::CA* caop(); + MB::CB* cbop(); + MA::CC* ccop(); + MA::CD* cdop(); + MA::IA* iaop(); + MB::IB1* ib1op(); + MB::IB2* ib2op(); + MA::IC* icop(); +}; + +}; diff --git a/python/test/Ice/inheritance/TestI.py b/python/test/Ice/inheritance/TestI.py new file mode 100644 index 00000000000..291e1b46414 --- /dev/null +++ b/python/test/Ice/inheritance/TestI.py @@ -0,0 +1,80 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test + +class CAI(Test.MA.CA): + def caop(self, p, current=None): + return p + +class CBI(Test.MB.CB, CAI): + def cbop(self, p, current=None): + return p + +class CCI(Test.MA.CC, CBI): + def ccop(self, p, current=None): + return p + +class IAI(Test.MA.IA): + def iaop(self, p, current=None): + return p + +class IB1I(Test.MB.IB1, IAI): + def ib1op(self, p, current=None): + return p + +class IB2I(Test.MB.IB2, IAI): + def ib2op(self, p, current=None): + return p + +class ICI(Test.MA.IC, IB1I, IB2I): + def icop(self, p, current=None): + return p + +class CDI(Test.MA.CD, CCI, IB1I, IB2I): + def cdop(self, p, current=None): + return p + +class InitialI(Test.Initial): + def __init__(self, adapter): + self._ca = Test.MA.CAPrx.uncheckedCast(adapter.addWithUUID(CAI())) + self._cb = Test.MB.CBPrx.uncheckedCast(adapter.addWithUUID(CBI())) + self._cc = Test.MA.CCPrx.uncheckedCast(adapter.addWithUUID(CCI())) + self._cd = Test.MA.CDPrx.uncheckedCast(adapter.addWithUUID(CDI())) + self._ia = Test.MA.IAPrx.uncheckedCast(adapter.addWithUUID(IAI())) + self._ib1 = Test.MB.IB1Prx.uncheckedCast(adapter.addWithUUID(IB1I())) + self._ib2 = Test.MB.IB2Prx.uncheckedCast(adapter.addWithUUID(IB2I())) + self._ic = Test.MA.ICPrx.uncheckedCast(adapter.addWithUUID(ICI())) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def caop(self, current=None): + return self._ca + + def cbop(self, current=None): + return self._cb + + def ccop(self, current=None): + return self._cc + + def cdop(self, current=None): + return self._cd + + def iaop(self, current=None): + return self._ia + + def ib1op(self, current=None): + return self._ib1 + + def ib2op(self, current=None): + return self._ib2 + + def icop(self, current=None): + return self._ic diff --git a/python/test/Ice/inheritance/run.py b/python/test/Ice/inheritance/run.py new file mode 100755 index 00000000000..9487c74a4f5 --- /dev/null +++ b/python/test/Ice/inheritance/run.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() +TestUtil.collocatedTest() diff --git a/python/test/Ice/location/AllTests.py b/python/test/Ice/location/AllTests.py new file mode 100644 index 00000000000..4fd5047e107 --- /dev/null +++ b/python/test/Ice/location/AllTests.py @@ -0,0 +1,256 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys + +class HelloI(Test.Hello): + def sayHello(self, current=None): + pass + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator, ref): + manager = Test.ServerManagerPrx.checkedCast(communicator.stringToProxy(ref)) + locator = communicator.getDefaultLocator() + test(manager) + + registry = Test.TestLocatorRegistryPrx.checkedCast(locator.getRegistry()); + test(registry); + + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + base = communicator.stringToProxy("test @ TestAdapter") + base2 = communicator.stringToProxy("test @ TestAdapter") + base3 = communicator.stringToProxy("test") + base4 = communicator.stringToProxy("ServerManager") + base5 = communicator.stringToProxy("test2") + print("ok") + + sys.stdout.write("testing ice_locator and ice_getLocator... ") + sys.stdout.flush() + test(Ice.proxyIdentityEqual(base.ice_getLocator(), communicator.getDefaultLocator())); + anotherLocator = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("anotherLocator")); + base = base.ice_locator(anotherLocator); + test(Ice.proxyIdentityEqual(base.ice_getLocator(), anotherLocator)); + communicator.setDefaultLocator(None); + base = communicator.stringToProxy("test @ TestAdapter"); + test(not base.ice_getLocator()); + base = base.ice_locator(anotherLocator); + test(Ice.proxyIdentityEqual(base.ice_getLocator(), anotherLocator)); + communicator.setDefaultLocator(locator); + base = communicator.stringToProxy("test @ TestAdapter"); + test(Ice.proxyIdentityEqual(base.ice_getLocator(), communicator.getDefaultLocator())); + + # + # We also test ice_router/ice_getRouter (perhaps we should add a + # test/Ice/router test?) + # + test(not base.ice_getRouter()); + anotherRouter = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("anotherRouter")); + base = base.ice_router(anotherRouter); + test(Ice.proxyIdentityEqual(base.ice_getRouter(), anotherRouter)); + router = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("dummyrouter")); + communicator.setDefaultRouter(router); + base = communicator.stringToProxy("test @ TestAdapter"); + test(Ice.proxyIdentityEqual(base.ice_getRouter(), communicator.getDefaultRouter())); + communicator.setDefaultRouter(None); + base = communicator.stringToProxy("test @ TestAdapter"); + test(not base.ice_getRouter()); + print("ok") + + sys.stdout.write("starting server... ") + sys.stdout.flush() + manager.startServer() + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + obj = Test.TestIntfPrx.checkedCast(base) + obj = Test.TestIntfPrx.checkedCast(communicator.stringToProxy("test@TestAdapter")) + obj = Test.TestIntfPrx.checkedCast(communicator.stringToProxy("test @TestAdapter")) + obj = Test.TestIntfPrx.checkedCast(communicator.stringToProxy("test@ TestAdapter")) + test(obj) + obj2 = Test.TestIntfPrx.checkedCast(base2) + test(obj2) + obj3 = Test.TestIntfPrx.checkedCast(base3) + test(obj3) + obj4 = Test.ServerManagerPrx.checkedCast(base4) + test(obj4) + obj5 = Test.TestIntfPrx.checkedCast(base5) + test(obj5) + print("ok") + + sys.stdout.write("testing id@AdapterId indirect proxy... ") + sys.stdout.flush() + obj.shutdown() + manager.startServer() + try: + obj2 = Test.TestIntfPrx.checkedCast(base2) + obj2.ice_ping() + except Ice.LocalException: + test(False) + print("ok") + + sys.stdout.write("testing identity indirect proxy... ") + sys.stdout.flush() + obj.shutdown() + manager.startServer() + try: + obj3 = Test.TestIntfPrx.checkedCast(base3) + obj3.ice_ping() + except Ice.LocalException: + test(False) + try: + obj2 = Test.TestIntfPrx.checkedCast(base2) + obj2.ice_ping() + except Ice.LocalException: + test(False) + obj.shutdown() + manager.startServer() + try: + obj2 = Test.TestIntfPrx.checkedCast(base2) + obj2.ice_ping() + except Ice.LocalException: + test(False) + try: + obj3 = Test.TestIntfPrx.checkedCast(base3) + obj3.ice_ping() + except Ice.LocalException: + test(False) + obj.shutdown() + manager.startServer() + + try: + obj2 = Test.TestIntfPrx.checkedCast(base2) + obj2.ice_ping() + except Ice.LocalException: + test(False) + obj.shutdown() + manager.startServer() + try: + obj3 = Test.TestIntfPrx.checkedCast(base3) + obj3.ice_ping() + except Ice.LocalException: + test(False) + obj.shutdown() + manager.startServer() + try: + obj2 = Test.TestIntfPrx.checkedCast(base2) + obj2.ice_ping() + except Ice.LocalException: + test(False) + obj.shutdown() + manager.startServer() + + try: + obj5 = Test.TestIntfPrx.checkedCast(base5) + obj5.ice_ping() + except Ice.LocalException: + test(False) + print("ok") + + sys.stdout.write("testing reference with unknown identity... ") + sys.stdout.flush() + try: + base = communicator.stringToProxy("unknown/unknown") + base.ice_ping() + test(False) + except Ice.NotRegisteredException as ex: + test(ex.kindOfObject == "object") + test(ex.id == "unknown/unknown") + print("ok") + + sys.stdout.write("testing reference with unknown adapter... ") + sys.stdout.flush() + try: + base = communicator.stringToProxy("test @ TestAdapterUnknown") + base.ice_ping() + test(False) + except Ice.NotRegisteredException as ex: + test(ex.kindOfObject == "object adapter") + test(ex.id == "TestAdapterUnknown") + print("ok") + + sys.stdout.write("testing object reference from server... ") + sys.stdout.flush() + hello = obj.getHello() + hello.sayHello() + print("ok") + + sys.stdout.write("testing object reference from server after shutdown... ") + sys.stdout.flush() + obj.shutdown() + manager.startServer() + hello.sayHello() + print("ok") + + sys.stdout.write("testing object migration... ") + sys.stdout.flush() + hello = Test.HelloPrx.checkedCast(communicator.stringToProxy("hello")) + obj.migrateHello() + hello.ice_getConnection().close(False); + hello.sayHello() + obj.migrateHello() + hello.sayHello() + obj.migrateHello() + hello.sayHello() + print("ok") + + sys.stdout.write("shutdown server... ") + sys.stdout.flush() + obj.shutdown() + print("ok") + + sys.stdout.write("testing whether server is gone... ") + sys.stdout.flush() + try: + obj2.ice_ping() + test(False) + except Ice.LocalException: + pass + try: + obj3.ice_ping() + test(False) + except Ice.LocalException: + pass + try: + obj5.ice_ping() + test(False) + except Ice.LocalException: + pass + print("ok") + + # + # Set up test for calling a collocated object through an indirect, adapterless reference. + # + sys.stdout.write("testing indirect references to collocated objects... ") + sys.stdout.flush() + properties = communicator.getProperties(); + properties.setProperty("Ice.PrintAdapterReady", "0"); + adapter = communicator.createObjectAdapterWithEndpoints("Hello", "default"); + adapter.setLocator(locator); + assert(adapter.getLocator() == locator) + + id = Ice.Identity(); + id.name = Ice.generateUUID(); + registry.addObject(adapter.add(HelloI(), id)); + adapter.activate(); + + helloPrx = Test.HelloPrx.checkedCast(communicator.stringToProxy(communicator.identityToString(id))); + test(not helloPrx.ice_getConnection()); + + adapter.deactivate(); + print("ok") + + sys.stdout.write("shutdown server manager... ") + sys.stdout.flush() + manager.shutdown() + print("ok") diff --git a/python/test/Ice/location/Client.py b/python/test/Ice/location/Client.py new file mode 100755 index 00000000000..9ac5b7c03d1 --- /dev/null +++ b/python/test/Ice/location/Client.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test, AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + AllTests.allTests(communicator, "ServerManager:default -p 12010") + return True + +try: + data = Ice.InitializationData() + data.properties = Ice.createProperties(sys.argv) + data.properties.setProperty("Ice.Default.Locator", "locator:default -p 12010") + communicator = Ice.initialize(sys.argv, data) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/location/Server.py b/python/test/Ice/location/Server.py new file mode 100755 index 00000000000..481621a5efc --- /dev/null +++ b/python/test/Ice/location/Server.py @@ -0,0 +1,199 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test + +class ServerLocatorRegistry(Test.TestLocatorRegistry): + def __init__(self): + self._adapters = {} + self._objects = {} + + def setAdapterDirectProxy_async(self, cb, adapter, obj, current=None): + if obj: + self._adapters[adapter] = obj + else: + self._adapters.pop(adapter) + cb.ice_response() + + def setReplicatedAdapterDirectProxy_async(self, cb, adapter, replica, obj, current=None): + if obj: + self._adapters[adapter] = obj + self._adapters[replica] = obj + else: + self._adapters.pop(adapter) + self._adapters.pop(replica) + cb.ice_response() + + def setServerProcessProxy_async(self, id, proxy, current=None): + cb.ice_response() + + def addObject(self, obj, current=None): + self._objects[obj.ice_getIdentity()] = obj + + def getAdapter(self, adapter): + if adapter not in self._adapters: + raise Ice.AdapterNotFoundException() + return self._adapters[adapter] + + def getObject(self, id): + if id not in self._objects: + raise Ice.ObjectNotFoundException() + return self._objects[id] + +class ServerLocator(Test.TestLocator): + + def __init__(self, registry, registryPrx): + self._registry = registry + self._registryPrx = registryPrx + self._requestCount = 0 + + def findObjectById_async(self, response, id, current=None): + self._requestCount += 1 + response.ice_response(self._registry.getObject(id)) + + def findAdapterById_async(self, response, id, current=None): + self._requestCount += 1 + response.ice_response(self._registry.getAdapter(id)) + + def getRegistry(self, current=None): + return self._registryPrx + + def getRequestCount(self, current=None): + return self._requestCount + +class ServerManagerI(Test.ServerManager): + def __init__(self, registry, initData): + self._registry = registry + self._communicators = [] + self._initData = initData + self._initData.properties.setProperty("TestAdapter.Endpoints", "default") + self._initData.properties.setProperty("TestAdapter.AdapterId", "TestAdapter") + self._initData.properties.setProperty("TestAdapter.ReplicaGroupId", "ReplicatedAdapter") + self._initData.properties.setProperty("TestAdapter2.Endpoints", "default") + self._initData.properties.setProperty("TestAdapter2.AdapterId", "TestAdapter2") + + def startServer(self, current=None): + + # + # Simulate a server: create a new communicator and object + # adapter. The object adapter is started on a system allocated + # port. The configuration used here contains the Ice.Locator + # configuration variable. The new object adapter will register + # its endpoints with the locator and create references containing + # the adapter id instead of the endpoints. + # + serverCommunicator = Ice.initialize(data=initData) + self._communicators.append(serverCommunicator) + adapter = serverCommunicator.createObjectAdapter("TestAdapter") + + adapter2 = serverCommunicator.createObjectAdapter("TestAdapter2") + + locator = serverCommunicator.stringToProxy("locator:default -p 12010") + adapter.setLocator(Ice.LocatorPrx.uncheckedCast(locator)) + adapter2.setLocator(Ice.LocatorPrx.uncheckedCast(locator)) + + object = TestI(adapter, adapter2, self._registry) + self._registry.addObject(adapter.add(object, communicator.stringToIdentity("test"))) + self._registry.addObject(adapter.add(object, communicator.stringToIdentity("test2"))) + adapter.add(object, communicator.stringToIdentity("test3")) + + adapter.activate() + adapter2.activate() + + def shutdown(self, current=None): + for i in self._communicators: + i.destroy() + current.adapter.getCommunicator().shutdown() + +class HelloI(Test.Hello): + def sayHello(self, current=None): + pass + +class TestI(Test.TestIntf): + def __init__(self, adapter, adapter2, registry): + self._adapter1 = adapter + self._adapter2 = adapter2 + self._registry = registry + self._registry.addObject(self._adapter1.add(HelloI(), communicator.stringToIdentity("hello"))) + + def shutdown(self, current=None): + self._adapter1.getCommunicator().shutdown() + + def getHello(self, current=None): + return Test.HelloPrx.uncheckedCast(self._adapter1.createIndirectProxy(communicator.stringToIdentity("hello"))) + + def getReplicatedHello(self, current=None): + return Test.HelloPrx.uncheckedCast(self._adapter1.createProxy(communicator.stringToIdentity("hello"))) + + def migrateHello(self, current=None): + id = communicator.stringToIdentity("hello") + try: + self._registry.addObject(self._adapter2.add(self._adapter1.remove(id), id)) + except Ice.NotRegisteredException: + self._registry.addObject(self._adapter1.add(self._adapter2.remove(id), id)) + +def run(args, communicator, initData): + # + # Register the server manager. The server manager creates a new + # 'server' (a server isn't a different process, it's just a new + # communicator and object adapter). + # + properties = communicator.getProperties() + properties.setProperty("Ice.ThreadPool.Server.Size", "2") + properties.setProperty("ServerManager.Endpoints", "default -p 12010:udp") + + adapter = communicator.createObjectAdapter("ServerManager") + + # + # We also register a sample server locator which implements the + # locator interface, this locator is used by the clients and the + # 'servers' created with the server manager interface. + # + registry = ServerLocatorRegistry() + registry.addObject(adapter.createProxy(communicator.stringToIdentity("ServerManager"))) + object = ServerManagerI(registry, initData) + adapter.add(object, communicator.stringToIdentity("ServerManager")) + + registryPrx = Ice.LocatorRegistryPrx.uncheckedCast(adapter.add(registry, communicator.stringToIdentity("registry"))) + + locator = ServerLocator(registry, registryPrx) + adapter.add(locator, communicator.stringToIdentity("locator")) + + adapter.activate() + communicator.waitForShutdown() + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator, initData) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/location/Test.ice b/python/test/Ice/location/Test.ice new file mode 100644 index 00000000000..82840ead2b6 --- /dev/null +++ b/python/test/Ice/location/Test.ice @@ -0,0 +1,55 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Locator.ice> + +module Test +{ + +interface TestLocatorRegistry extends ::Ice::LocatorRegistry +{ + // + // Allow remote addition of objects to the locator registry. + // + void addObject(Object* obj); +}; + +interface TestLocator extends ::Ice::Locator +{ + // + // Returns the number of request on the locator interface. + // + ["cpp:const"] idempotent int getRequestCount(); +}; + +interface ServerManager +{ + void startServer(); + void shutdown(); +}; + +interface Hello +{ + void sayHello(); +}; + +interface TestIntf +{ + void shutdown(); + + Hello* getHello(); + + Hello* getReplicatedHello(); + + void migrateHello(); +}; + +}; diff --git a/python/test/Ice/location/run.py b/python/test/Ice/location/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/location/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Ice/objects/AllTests.py b/python/test/Ice/objects/AllTests.py new file mode 100644 index 00000000000..d7de69b901c --- /dev/null +++ b/python/test/Ice/objects/AllTests.py @@ -0,0 +1,226 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, TestI, sys + +class MyObjectFactory(Ice.ObjectFactory): + def create(self, type): + if type == '::Test::B': + return TestI.BI() + elif type == '::Test::C': + return TestI.CI() + elif type == '::Test::D': + return TestI.DI() + elif type == '::Test::E': + return TestI.EI() + elif type == '::Test::F': + return TestI.FI() + elif type == '::Test::I': + return TestI.II() + elif type == '::Test::J': + return TestI.JI() + elif type == '::Test::H': + return TestI.HI() + assert(False) # Should never be reached + + def destroy(self): + # Nothing to do + pass + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + factory = MyObjectFactory() + communicator.addObjectFactory(factory, '::Test::B') + communicator.addObjectFactory(factory, '::Test::C') + communicator.addObjectFactory(factory, '::Test::D') + communicator.addObjectFactory(factory, '::Test::E') + communicator.addObjectFactory(factory, '::Test::F') + communicator.addObjectFactory(factory, '::Test::I') + communicator.addObjectFactory(factory, '::Test::J') + communicator.addObjectFactory(factory, '::Test::H') + + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "initial:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + initial = Test.InitialPrx.checkedCast(base) + test(initial) + test(initial == base) + print("ok") + + sys.stdout.write("getting B1... ") + sys.stdout.flush() + b1 = initial.getB1() + test(b1) + print("ok") + + sys.stdout.write("getting B2... ") + sys.stdout.flush() + b2 = initial.getB2() + test(b2) + print("ok") + + sys.stdout.write("getting C... ") + sys.stdout.flush() + c = initial.getC() + test(c) + print("ok") + + sys.stdout.write("getting D... ") + sys.stdout.flush() + d = initial.getD() + test(d) + print("ok") + + sys.stdout.write("testing protected members... ") + sys.stdout.flush() + e = initial.getE() + test(e.checkValues()) + test(e._i == 1) + test(e._s == "hello") + f = initial.getF() + test(f.checkValues()) + test(f.e2.checkValues()) + test(f._e1.checkValues()) + print("ok") + + sys.stdout.write("getting I, J, H... ") + sys.stdout.flush() + i = initial.getI() + test(i) + j = initial.getJ() + test(isinstance(j, Test.J)) + h = initial.getH() + test(isinstance(h, Test.H)) + print("ok") + + sys.stdout.write("setting I... ") + sys.stdout.flush() + initial.setI(TestI.II()) + initial.setI(TestI.JI()) + initial.setI(TestI.HI()) + print("ok") + + sys.stdout.write("checking consistency... ") + sys.stdout.flush() + test(b1 != b2) + test(b1 != c) + test(b1 != d) + test(b2 != c) + test(b2 != d) + test(c != d) + test(b1.theB == b1) + test(b1.theC == None) + test(isinstance(b1.theA, Test.B)) + test(b1.theA.theA == b1.theA) + test(b1.theA.theB == b1) + test(b1.theA.theC) + test(b1.theA.theC.theB == b1.theA) + test(b1.preMarshalInvoked) + test(b1.postUnmarshalInvoked()) + test(b1.theA.preMarshalInvoked) + test(b1.theA.postUnmarshalInvoked()) + test(b1.theA.theC.preMarshalInvoked) + test(b1.theA.theC.postUnmarshalInvoked()) + # More tests possible for b2 and d, but I think this is already sufficient. + test(b2.theA == b2) + test(d.theC == None) + print("ok") + + sys.stdout.write("getting B1, B2, C, and D all at once... ") + sys.stdout.flush() + b1, b2, c, d = initial.getAll() + test(b1) + test(b2) + test(c) + test(d) + print("ok") + + sys.stdout.write("checking consistency... ") + sys.stdout.flush() + test(b1 != b2) + test(b1 != c) + test(b1 != d) + test(b2 != c) + test(b2 != d) + test(c != d) + test(b1.theA == b2) + test(b1.theB == b1) + test(b1.theC == None) + test(b2.theA == b2) + test(b2.theB == b1) + test(b2.theC == c) + test(c.theB == b2) + test(d.theA == b1) + test(d.theB == b2) + test(d.theC == None) + test(d.preMarshalInvoked) + test(d.postUnmarshalInvoked()) + test(d.theA.preMarshalInvoked) + test(d.theA.postUnmarshalInvoked()) + test(d.theB.preMarshalInvoked) + test(d.theB.postUnmarshalInvoked()) + test(d.theB.theC.preMarshalInvoked) + test(d.theB.theC.postUnmarshalInvoked()) + print("ok") + + sys.stdout.write("testing sequences... ") + try: + sys.stdout.flush() + initial.opBaseSeq([]) + + retS, outS = initial.opBaseSeq([Test.Base()]) + test(len(retS) == 1 and len(outS) == 1) + except Ice.OperationNotExistException: + pass + print("ok") + + sys.stdout.write("testing compact ID... ") + sys.stdout.flush() + try: + r = initial.getCompact() + test(r) + except Ice.OperationNotExistException: + pass + print("ok") + + # Don't run this test with collocation, this should work with collocation + # but the test isn't written to support it (we'd need support for the + # streaming interface) + if initial.ice_getConnection(): + sys.stdout.write("testing UnexpectedObjectException... ") + sys.stdout.flush() + ref = "uoet:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + uoet = Test.UnexpectedObjectExceptionTestPrx.uncheckedCast(base) + test(uoet) + try: + uoet.op() + test(False) + except Ice.UnexpectedObjectException as ex: + test(ex.type == "::Test::AlsoEmpty") + test(ex.expectedType == "::Test::Empty") + except Ice.Exception as ex: + print(ex) + test(False) + except: + print(sys.exc_info()) + test(False) + print("ok") + + return initial diff --git a/python/test/Ice/objects/Client.py b/python/test/Ice/objects/Client.py new file mode 100755 index 00000000000..ba3057aed04 --- /dev/null +++ b/python/test/Ice/objects/Client.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +Ice.loadSlice('ClientPrivate.ice') +import AllTests + +def run(args, communicator): + initial = AllTests.allTests(communicator) + initial.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/objects/ClientPrivate.ice b/python/test/Ice/objects/ClientPrivate.ice new file mode 100644 index 00000000000..31d2e12d833 --- /dev/null +++ b/python/test/Ice/objects/ClientPrivate.ice @@ -0,0 +1,68 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class Empty +{ +}; + +class AlsoEmpty +{ +}; + +interface UnexpectedObjectExceptionTest +{ + Empty op(); +}; + +// +// Remaining definitions are here to ensure that the generated code compiles. +// + +class COneMember +{ + Empty e; +}; + +class CTwoMembers +{ + Empty e1; + Empty e2; +}; + +exception EOneMember +{ + Empty e; +}; + +exception ETwoMembers +{ + Empty e1; + Empty e2; +}; + +struct SOneMember +{ + Empty e; +}; + +struct STwoMembers +{ + Empty e1; + Empty e2; +}; + +dictionary<int, COneMember> DOneMember; +dictionary<int, CTwoMembers> DTwoMembers; + +}; diff --git a/python/test/Ice/objects/Collocated.py b/python/test/Ice/objects/Collocated.py new file mode 100755 index 00000000000..321c351de56 --- /dev/null +++ b/python/test/Ice/objects/Collocated.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +Ice.loadSlice('ClientPrivate.ice') +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + initial = TestI.InitialI(adapter) + adapter.add(initial, communicator.stringToIdentity("initial")) + uoet = TestI.UnexpectedObjectExceptionTestI() + adapter.add(uoet, communicator.stringToIdentity("uoet")) + #adapter.activate() // Don't activate OA to ensure collocation is used. + + AllTests.allTests(communicator) + + # We must call shutdown even in the collocated case for cyclic dependency cleanup + initial.shutdown() + + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/objects/Server.py b/python/test/Ice/objects/Server.py new file mode 100755 index 00000000000..d988b501d14 --- /dev/null +++ b/python/test/Ice/objects/Server.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +Ice.loadSlice('ServerPrivate.ice') +import Test, TestI + +class MyObjectFactory(Ice.ObjectFactory): + def create(self, type): + if type == '::Test::I': + return TestI.II() + elif type == '::Test::J': + return TestI.JI() + elif type == '::Test::H': + return TestI.HI() + assert(False) # Should never be reached + + def destroy(self): + # Nothing to do + pass + +def run(args, communicator): + factory = MyObjectFactory() + communicator.addObjectFactory(factory, '::Test::I') + communicator.addObjectFactory(factory, '::Test::J') + communicator.addObjectFactory(factory, '::Test::H') + + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + initial = TestI.InitialI(adapter) + adapter.add(initial, communicator.stringToIdentity("initial")) + uoet = TestI.UnexpectedObjectExceptionTestI() + adapter.add(uoet, communicator.stringToIdentity("uoet")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/objects/ServerPrivate.ice b/python/test/Ice/objects/ServerPrivate.ice new file mode 100644 index 00000000000..f7920ba6de8 --- /dev/null +++ b/python/test/Ice/objects/ServerPrivate.ice @@ -0,0 +1,68 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class Empty +{ +}; + +class AlsoEmpty +{ +}; + +interface UnexpectedObjectExceptionTest +{ + AlsoEmpty op(); +}; + +// +// Remaining definitions are here to ensure that the generated code compiles. +// + +class COneMember +{ + Empty e; +}; + +class CTwoMembers +{ + Empty e1; + Empty e2; +}; + +exception EOneMember +{ + Empty e; +}; + +exception ETwoMembers +{ + Empty e1; + Empty e2; +}; + +struct SOneMember +{ + Empty e; +}; + +struct STwoMembers +{ + Empty e1; + Empty e2; +}; + +dictionary<int, COneMember> DOneMember; +dictionary<int, CTwoMembers> DTwoMembers; + +}; diff --git a/python/test/Ice/objects/Test.ice b/python/test/Ice/objects/Test.ice new file mode 100644 index 00000000000..42852d1f75c --- /dev/null +++ b/python/test/Ice/objects/Test.ice @@ -0,0 +1,131 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +struct S +{ + string str; +}; + +class Base +{ + S theS; + string str; +}; + +class AbstractBase extends Base +{ + void op(); +}; + +class B; +class C; + +class A +{ + B theB; + C theC; + + bool preMarshalInvoked; + bool postUnmarshalInvoked(); +}; + +class B extends A +{ + A theA; +}; + +class C +{ + B theB; + + bool preMarshalInvoked; + bool postUnmarshalInvoked(); +}; + +class D +{ + A theA; + B theB; + C theC; + + bool preMarshalInvoked; + bool postUnmarshalInvoked(); +}; + +["protected"] class E +{ + int i; + string s; + + bool checkValues(); +}; + +class F +{ + ["protected"] E e1; + E e2; + + bool checkValues(); +}; + +interface I +{ +}; + +interface J extends I +{ +}; + +class H implements I +{ +}; + +sequence<Base> BaseSeq; + +class CompactExt; + +class Compact(1) +{ +}; + +const int CompactExtId = 789; + +class CompactExt(CompactExtId) extends Compact +{ +}; + +class Initial +{ + void shutdown(); + B getB1(); + B getB2(); + C getC(); + D getD(); + E getE(); + F getF(); + + void getAll(out B b1, out B b2, out C theC, out D theD); + + I getI(); + I getJ(); + I getH(); + + void setI(I theI); + + BaseSeq opBaseSeq(BaseSeq inSeq, out BaseSeq outSeq); + + Compact getCompact(); +}; + +}; diff --git a/python/test/Ice/objects/TestI.py b/python/test/Ice/objects/TestI.py new file mode 100644 index 00000000000..5fc8b0cedca --- /dev/null +++ b/python/test/Ice/objects/TestI.py @@ -0,0 +1,162 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test + +class BI(Test.B): + def __init__(self): + self.preMarshalInvoked = False + self._postUnmarshalInvoked = False + + def postUnmarshalInvoked(self, current=None): + return self._postUnmarshalInvoked + + def ice_preMarshal(self): + self.preMarshalInvoked = True + + def ice_postUnmarshal(self): + self._postUnmarshalInvoked = True + +class CI(Test.C): + def __init__(self): + self.preMarshalInvoked = False + self._postUnmarshalInvoked = False + + def postUnmarshalInvoked(self, current=None): + return self._postUnmarshalInvoked + + def ice_preMarshal(self): + self.preMarshalInvoked = True + + def ice_postUnmarshal(self): + self._postUnmarshalInvoked = True + +class DI(Test.D): + def __init__(self): + self.preMarshalInvoked = False + self._postUnmarshalInvoked = False + + def postUnmarshalInvoked(self, current=None): + return self._postUnmarshalInvoked + + def ice_preMarshal(self): + self.preMarshalInvoked = True + + def ice_postUnmarshal(self): + self._postUnmarshalInvoked = True + +class EI(Test.E): + def __init__(self): + Test.E.__init__(self, 1, "hello") + + def checkValues(self, current=None): + return self._i == 1 and self._s == "hello" + +class FI(Test.F): + def __init__(self, e=None): + Test.F.__init__(self, e, e) + + def checkValues(self, current=None): + return self._e1 != None and self._e1 == self.e2 + +class II(Test.I): + pass + +class JI(Test.J): + pass + +class HI(Test.H): + pass + +class InitialI(Test.Initial): + def __init__(self, adapter): + self._adapter = adapter + self._b1 = BI() + self._b2 = BI() + self._c = CI() + self._d = DI() + self._e = EI() + self._f = FI(self._e) + + self._b1.theA = self._b2 # Cyclic reference to another B + self._b1.theB = self._b1 # Self reference. + self._b1.theC = None # Null reference. + + self._b2.theA = self._b2 # Self reference, using base. + self._b2.theB = self._b1 # Cyclic reference to another B + self._b2.theC = self._c # Cyclic reference to a C. + + self._c.theB = self._b2 # Cyclic reference to a B. + + self._d.theA = self._b1 # Reference to a B. + self._d.theB = self._b2 # Reference to a B. + self._d.theC = None # Reference to a C. + + def shutdown(self, current=None): + self._adapter.getCommunicator().shutdown() + + def getB1(self, current=None): + self._b1.preMarshalInvoked = False + self._b2.preMarshalInvoked = False + self._c.preMarshalInvoked = False + return self._b1 + + def getB2(self, current=None): + self._b1.preMarshalInvoked = False + self._b2.preMarshalInvoked = False + self._c.preMarshalInvoked = False + return self._b2 + + def getC(self, current=None): + self._b1.preMarshalInvoked = False + self._b2.preMarshalInvoked = False + self._c.preMarshalInvoked = False + return self._c + + def getD(self, current=None): + self._b1.preMarshalInvoked = False + self._b2.preMarshalInvoked = False + self._c.preMarshalInvoked = False + self._d.preMarshalInvoked = False + return self._d + + def getE(self, current=None): + return self._e + + def getF(self, current=None): + return self._f + + def getAll(self, current=None): + self._b1.preMarshalInvoked = False + self._b2.preMarshalInvoked = False + self._c.preMarshalInvoked = False + self._d.preMarshalInvoked = False + return (self._b1, self._b2, self._c, self._d) + + def getI(self, current=None): + return II() + + def getJ(self, current=None): + return JI() + + def getH(self, current=None): + return HI() + + def setI(self, i, current=None): + pass + + def opBaseSeq(self, inSeq, current=None): + return (inSeq, inSeq) + + def getCompact(self, current=None): + return Test.CompactExt() + +class UnexpectedObjectExceptionTestI(Test.UnexpectedObjectExceptionTest): + def op(self, current=None): + return Test.AlsoEmpty() diff --git a/python/test/Ice/objects/run.py b/python/test/Ice/objects/run.py new file mode 100755 index 00000000000..9e92332d98b --- /dev/null +++ b/python/test/Ice/objects/run.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with compact (default) format.") +TestUtil.clientServerTest() + +print("Running test with sliced format.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat", + additionalServerOptions="--Ice.Default.SlicedFormat") + +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running collocated test.") +TestUtil.collocatedTest() diff --git a/python/test/Ice/operations/AllTests.py b/python/test/Ice/operations/AllTests.py new file mode 100644 index 00000000000..a3d3bac823a --- /dev/null +++ b/python/test/Ice/operations/AllTests.py @@ -0,0 +1,57 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, Twoways, TwowaysAMI, Oneways, OnewaysAMI, BatchOneways, sys +import BatchOnewaysAMI + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + ref = "test:default -p 12010" + base = communicator.stringToProxy(ref) + cl = Test.MyClassPrx.checkedCast(base) + derived = Test.MyDerivedClassPrx.checkedCast(cl) + + sys.stdout.write("testing twoway operations... ") + sys.stdout.flush() + Twoways.twoways(communicator, cl) + Twoways.twoways(communicator, derived) + derived.opDerived() + print("ok") + + sys.stdout.write("testing oneway operations... ") + sys.stdout.flush() + Oneways.oneways(communicator, cl) + print("ok") + + sys.stdout.write("testing twoway operations with AMI... ") + sys.stdout.flush() + TwowaysAMI.twowaysAMI(communicator, cl) + print("ok") + + sys.stdout.write("testing oneway operations with AMI... ") + sys.stdout.flush() + OnewaysAMI.onewaysAMI(communicator, cl) + print("ok") + + sys.stdout.write("testing batch oneway operations... ") + sys.stdout.flush() + BatchOneways.batchOneways(cl) + BatchOneways.batchOneways(derived) + print("ok") + + sys.stdout.write("testing batch AMI oneway operations... ") + sys.stdout.flush() + BatchOnewaysAMI.batchOneways(cl) + BatchOnewaysAMI.batchOneways(derived) + print("ok") + + return cl diff --git a/python/test/Ice/operations/BatchOneways.py b/python/test/Ice/operations/BatchOneways.py new file mode 100644 index 00000000000..0e73c6f1a2d --- /dev/null +++ b/python/test/Ice/operations/BatchOneways.py @@ -0,0 +1,145 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, array, sys, time + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class BatchRequestInterceptorI(Ice.BatchRequestInterceptor): + + def __init__(self): + self._enabled = False + self._count = 0 + self._size = 0 + self._lastRequestSize = 0 + + def enqueue(self, request, count, size): + test(request.getOperation() == "opByteSOneway" or request.getOperation() == "ice_ping") + test(request.getProxy().ice_isBatchOneway()) + + if count > 0: + test(self._lastRequestSize + self._size == size) + + self._count = count + self._size = size + + if self._size + request.getSize() > 25000: + request.getProxy().begin_ice_flushBatchRequests() + self._size = 18 # header + + if self._enabled: + self._lastRequestSize = request.getSize() + self._count += 1 + request.enqueue() + + def setEnabled(self, v): + self._enabled = v + + def count(self): + return self._count + +def batchOneways(p): + + if sys.version_info[0] == 2: + bs1 = [] + bs1[0:10 * 1024] = range(0, 10 * 1024) # add 100,000 entries. + bs1 = ['\x00' for x in bs1] # set them all to \x00 + bs1 = ''.join(bs1) # make into a byte array + else: + bs1 = bytes([0 for x in range(0, 10 * 1024)]) + + try: + p.opByteSOneway(bs1) + except Ice.MemoryLimitException: + test(False) + + batch = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + + batch.ice_flushBatchRequests() # Empty flush + + p.opByteSOnewayCallCount() # Reset the call count + + for i in range(30): + batch.opByteSOneway(bs1) + + count = 0 + while count < 27: # 3 * 9 requests auto-flushed. + count += p.opByteSOnewayCallCount() + time.sleep(0.01) + + if p.ice_getConnection(): + batch1 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + batch2 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + + batch1.ice_ping() + batch2.ice_ping() + batch1.ice_flushBatchRequests() + batch1.ice_getConnection().close(False) + batch1.ice_ping() + batch2.ice_ping() + + batch1.ice_getConnection() + batch2.ice_getConnection() + + batch1.ice_ping() + batch1.ice_getConnection().close(False) + + batch1.ice_ping() + batch2.ice_ping() + + identity = Ice.Identity() + identity.name = "invalid"; + batch3 = batch.ice_identity(identity) + batch3.ice_ping() + batch3.ice_flushBatchRequests() + + # Make sure that a bogus batch request doesn't cause troubles to other ones. + batch3.ice_ping() + batch.ice_ping() + batch.ice_flushBatchRequests() + batch.ice_ping() + + if batch.ice_getConnection(): + initData = Ice.InitializationData() + initData.properties = p.ice_getCommunicator().getProperties().clone() + interceptor = BatchRequestInterceptorI() + initData.batchRequestInterceptor = interceptor + + ic = Ice.initialize(data=initData) + + batch = Test.MyClassPrx.uncheckedCast(ic.stringToProxy(p.ice_toString())).ice_batchOneway() + + test(interceptor.count() == 0) + batch.ice_ping() + batch.ice_ping() + batch.ice_ping() + test(interceptor.count() == 0) + + interceptor.setEnabled(True) + batch.ice_ping() + batch.ice_ping() + batch.ice_ping() + test(interceptor.count() == 3) + + batch.ice_flushBatchRequests() + batch.ice_ping() + test(interceptor.count() == 1) + + batch.opByteSOneway(bs1) + test(interceptor.count() == 2) + batch.opByteSOneway(bs1) + test(interceptor.count() == 3) + + batch.opByteSOneway(bs1) # This should trigger the flush + batch.ice_ping() + test(interceptor.count() == 2) + + ic.destroy() diff --git a/python/test/Ice/operations/BatchOnewaysAMI.py b/python/test/Ice/operations/BatchOnewaysAMI.py new file mode 100644 index 00000000000..f78bf40db04 --- /dev/null +++ b/python/test/Ice/operations/BatchOnewaysAMI.py @@ -0,0 +1,90 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, array, sys, threading, time + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class Callback: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +def batchOneways(p): + + if sys.version_info[0] == 2: + bs1 = [] + bs1[0:10 * 1024] = range(0, 10 * 1024) # add 100,000 entries. + bs1 = ['\x00' for x in bs1] # set them all to \x00 + bs1 = ''.join(bs1) # make into a byte array + else: + bs1 = bytes([0 for x in range(0, 10 * 1024)]) + batch = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + + batch.end_ice_flushBatchRequests(batch.begin_ice_flushBatchRequests()) # Empty flush + test(batch.begin_ice_flushBatchRequests().isSent()) # Empty flush + test(batch.begin_ice_flushBatchRequests().isCompleted()) # Empty flush + test(batch.begin_ice_flushBatchRequests().sentSynchronously()) # Empty flush + + for i in range(30): + batch.begin_opByteSOneway(bs1, lambda: 0, lambda ex: test(False) ) + + count = 0 + while count < 27: # 3 * 9 requests auto-flushed. + count += p.opByteSOnewayCallCount() + time.sleep(0.01) + + if p.ice_getConnection(): + + batch1 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + batch2 = Test.MyClassPrx.uncheckedCast(p.ice_batchOneway()) + + batch1.end_ice_ping(batch1.begin_ice_ping()) + batch2.end_ice_ping(batch2.begin_ice_ping()) + batch1.end_ice_flushBatchRequests(batch1.begin_ice_flushBatchRequests()) + batch1.ice_getConnection().close(False) + batch1.end_ice_ping(batch1.begin_ice_ping()) + batch2.end_ice_ping(batch2.begin_ice_ping()) + + batch1.ice_getConnection() + batch2.ice_getConnection() + + batch1.ice_getConnection().close(False) + + batch1.end_ice_ping(batch1.begin_ice_ping()) + batch2.end_ice_ping(batch2.begin_ice_ping()) + + identity = Ice.Identity() + identity.name = "invalid"; + batch3 = batch.ice_identity(identity) + batch3.ice_ping() + batch3.end_ice_flushBatchRequests(batch3.begin_ice_flushBatchRequests()) + + # Make sure that a bogus batch request doesn't cause troubles to other ones. + batch3.ice_ping() + batch.ice_ping() + batch.end_ice_flushBatchRequests(batch.begin_ice_flushBatchRequests()) + batch.ice_ping() diff --git a/python/test/Ice/operations/Client.py b/python/test/Ice/operations/Client.py new file mode 100755 index 00000000000..2c18f66d07d --- /dev/null +++ b/python/test/Ice/operations/Client.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + myClass = AllTests.allTests(communicator) + + sys.stdout.write("testing server shutdown... ") + sys.stdout.flush() + myClass.shutdown() + try: + myClass.opVoid() + test(False) + except Ice.LocalException: + print("ok") + + return True + +try: + # + # In this test, we need at least two threads in the + # client side thread pool for nested AMI. + # + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty('Ice.ThreadPool.Client.Size', '2') + initData.properties.setProperty('Ice.ThreadPool.Client.SizeWarn', '0') + initData.properties.setProperty("Ice.BatchAutoFlushSize", "100") + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/operations/Collocated.py b/python/test/Ice/operations/Collocated.py new file mode 100755 index 00000000000..cabd7890618 --- /dev/null +++ b/python/test/Ice/operations/Collocated.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + prx = adapter.add(TestI.MyDerivedClassI(), communicator.stringToIdentity("test")) + #adapter.activate() // Don't activate OA to ensure collocation is used. + + if prx.ice_getConnection(): + raise RuntimeError("collocation doesn't work") + + cl = AllTests.allTests(communicator) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + + initData.properties.setProperty("Ice.BatchAutoFlushSize", "100") + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/operations/Oneways.py b/python/test/Ice/operations/Oneways.py new file mode 100644 index 00000000000..a64d9103ce9 --- /dev/null +++ b/python/test/Ice/operations/Oneways.py @@ -0,0 +1,46 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, math, Test, array + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def oneways(communicator, p): + + p = Test.MyClassPrx.uncheckedCast(p.ice_oneway()) + + # + # ice_ping + # + p.ice_ping() + + # + # opVoid + # + p.opVoid() + + # + # opIdempotent + # + p.opIdempotent() + + # + # opNonmutating + # + p.opNonmutating() + + # + # opByte + # + try: + p.opByte(0xff, 0x0f) + except Ice.TwowayOnlyException: + pass diff --git a/python/test/Ice/operations/OnewaysAMI.py b/python/test/Ice/operations/OnewaysAMI.py new file mode 100644 index 00000000000..1068cb2e9b0 --- /dev/null +++ b/python/test/Ice/operations/OnewaysAMI.py @@ -0,0 +1,85 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def sent(self, sentSynchronously): + self.called() + + def noException(self, ex): + test(False) + +def onewaysAMI(communicator, proxy): + + p = Test.MyClassPrx.uncheckedCast(proxy.ice_oneway()) + + cb = Callback() + p.begin_ice_ping(None, cb.noException, cb.sent) + cb.check() + + try: + p.begin_ice_isA(Test.MyClass.ice_staticId()) + test(False) + except RuntimeError: + pass + + try: + p.begin_ice_id() + test(False) + except RuntimeError: + pass + + try: + p.begin_ice_ids() + test(False) + except RuntimeError: + pass + + cb = Callback() + p.begin_opVoid(None, cb.noException, cb.sent) + cb.check() + + cb = Callback() + p.begin_opIdempotent(None, cb.noException, cb.sent) + cb.check() + + cb = Callback() + p.begin_opNonmutating(None, cb.noException, cb.sent) + cb.check() + + try: + p.begin_opByte(0xff, 0x0f) + test(False) + except RuntimeError: + pass diff --git a/python/test/Ice/operations/Server.py b/python/test/Ice/operations/Server.py new file mode 100755 index 00000000000..b7f2045fd1b --- /dev/null +++ b/python/test/Ice/operations/Server.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice('"-I' + slice_dir + '" Test.ice') +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TestI.MyDerivedClassI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + # + # Its possible to have batch oneway requests dispatched after the + # adapter is deactivated due to thread scheduling so we supress + # this warning. + # + initData.properties.setProperty("Ice.Warn.Dispatch", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/operations/ServerAMD.py b/python/test/Ice/operations/ServerAMD.py new file mode 100755 index 00000000000..61565b37353 --- /dev/null +++ b/python/test/Ice/operations/ServerAMD.py @@ -0,0 +1,432 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, threading + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' TestAMD.ice") +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class Thread_opVoid(threading.Thread): + def __init__(self, cb): + threading.Thread.__init__(self) + self.cb = cb + + def run(self): + self.cb.ice_response() + +class MyDerivedClassI(Test.MyDerivedClass): + def __init__(self): + self.opVoidThread = None + self.opVoidThreadLock = threading.Lock() + self.lock = threading.Lock() + self.opByteSOnewayCount = 0 + + def ice_isA(self, id, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_isA(self, id, current) + + def ice_ping(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + Test.MyDerivedClass.ice_ping(self, current) + + def ice_ids(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_ids(self, current) + + def ice_id(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_id(self, current) + + def shutdown_async(self, cb, current=None): + self.opVoidThreadLock.acquire() + if self.opVoidThread: + self.opVoidThread.join() + self.opVoidThread = None + self.opVoidThreadLock.release() + + current.adapter.getCommunicator().shutdown() + cb.ice_response() + + def opVoid_async(self, cb, current=None): + test(current.mode == Ice.OperationMode.Normal) + + self.opVoidThreadLock.acquire() + if self.opVoidThread: + self.opVoidThread.join() + self.opVoidThread = None + + self.opVoidThread = Thread_opVoid(cb) + self.opVoidThread.start() + self.opVoidThreadLock.release() + + def opByte_async(self, cb, p1, p2, current=None): + cb.ice_response(p1, p1 ^ p2) + + def opBool_async(self, cb, p1, p2, current=None): + cb.ice_response(p2, p1) + + def opShortIntLong_async(self, cb, p1, p2, p3, current=None): + cb.ice_response(p3, p1, p2, p3) + + def opFloatDouble_async(self, cb, p1, p2, current=None): + cb.ice_response(p2, p1, p2) + + def opString_async(self, cb, p1, p2, current=None): + cb.ice_response(p1 + " " + p2, p2 + " " + p1) + + def opMyEnum_async(self, cb, p1, current=None): + cb.ice_response(Test.MyEnum.enum3, p1) + + def opMyClass_async(self, cb, p1, current=None): + p2 = p1 + p3 = Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(communicator.stringToIdentity("noSuchIdentity"))) + cb.ice_response(Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)), p2, p3) + + def opStruct_async(self, cb, p1, p2, current=None): + p1.s.s = "a new string" + cb.ice_response(p2, p1) + + def opByteS_async(self, cb, p1, p2, current=None): + if sys.version_info[0] == 2: + # By default sequence<byte> maps to a string. + p3 = map(ord, p1) + p3.reverse() + r = map(ord, p1) + r.extend(map(ord, p2)) + else: + p3 = bytes(reversed(p1)) + r = p1 + p2 + cb.ice_response(r, p3) + + def opBoolS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse(); + cb.ice_response(r, p3) + + def opShortIntLongS_async(self, cb, p1, p2, p3, current=None): + p4 = p1[0:] + p5 = p2[0:] + p5.reverse() + p6 = p3[0:] + p6.extend(p3) + cb.ice_response(p3, p4, p5, p6) + + def opFloatDoubleS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p4 = p2[0:] + p4.reverse() + r = p2[0:] + r.extend(p1) + cb.ice_response(r, p3, p4) + + def opStringS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse() + cb.ice_response(r, p3) + + def opByteSS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.reverse() + r = p1[0:] + r.extend(p2) + cb.ice_response(r, p3) + + def opBoolSS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse() + cb.ice_response(r, p3) + + def opShortIntLongSS_async(self, cb, p1, p2, p3, current=None): + p4 = p1[0:] + p5 = p2[0:] + p5.reverse() + p6 = p3[0:] + p6.extend(p3) + cb.ice_response(p3, p4, p5, p6) + + def opFloatDoubleSS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p4 = p2[0:] + p4.reverse() + r = p2[0:] + r.extend(p2) + cb.ice_response(r, p3, p4) + + def opStringSS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p2[0:] + r.reverse() + cb.ice_response(r, p3) + + def opStringSSS_async(self, cb, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p2[0:] + r.reverse() + cb.ice_response(r, p3) + + def opByteBoolD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opShortIntD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opLongFloatD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opStringStringD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opStringMyEnumD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opMyEnumStringD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opMyStructMyEnumD_async(self, cb, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opByteBoolDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opShortIntDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opLongFloatDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opStringStringDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opStringMyEnumDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opMyEnumStringDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opMyStructMyEnumDS_async(self, cb, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + cb.ice_response(r, p3) + + def opByteByteSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opBoolBoolSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opShortShortSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opIntIntSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opLongLongSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opStringFloatSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opStringDoubleSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opStringStringSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opMyEnumMyEnumSD_async(self, cb, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + cb.ice_response(r, p3) + + def opIntS_async(self, cb, s, current=None): + cb.ice_response([-x for x in s]) + + def opByteSOneway_async(self, cb, s, current=None): + self.lock.acquire() + self.opByteSOnewayCount += 1 + self.lock.release() + cb.ice_response() + + def opByteSOnewayCallCount_async(self, cb, current=None): + self.lock.acquire() + count = self.opByteSOnewayCount + self.opByteSOnewayCount = 0 + self.lock.release() + cb.ice_response(count) + + def opDoubleMarshaling_async(self, cb, p1, p2, current=None): + d = 1278312346.0 / 13.0; + test(p1 == d) + for i in p2: + test(i == d) + cb.ice_response() + + def opContext_async(self, cb, current=None): + cb.ice_response(current.ctx) + + def opIdempotent_async(self, cb, current=None): + test(current.mode == Ice.OperationMode.Idempotent) + cb.ice_response() + + def opNonmutating_async(self, cb, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + cb.ice_response() + + def opDerived_async(self, cb, current=None): + cb.ice_response() + + def opByte1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opShort1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opInt1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opLong1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opFloat1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opDouble1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opString1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opStringS1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opByteBoolD1_async(self, cb, value, current=None): + cb.ice_response(value) + + def opStringS2_async(self, cb, value, current=None): + cb.ice_response(value) + + def opByteBoolD2_async(self, cb, value, current=None): + cb.ice_response(value) + + def opMyClass1_async(self, cb, value, current=None): + return cb.ice_response(value) + + def opMyStruct1_async(self, cb, value, current=None): + return cb.ice_response(value) + + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(MyDerivedClassI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Dispatch", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/operations/Test.ice b/python/test/Ice/operations/Test.ice new file mode 100644 index 00000000000..324fa1bf633 --- /dev/null +++ b/python/test/Ice/operations/Test.ice @@ -0,0 +1,272 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +enum MyEnum +{ + enum1, + enum2, + enum3 +}; + +class MyClass; + +struct AnotherStruct +{ + string s; +}; + +struct Structure +{ + MyClass* p; + MyEnum e; + AnotherStruct s; +}; + +sequence<byte> ByteS; +sequence<bool> BoolS; +sequence<short> ShortS; +sequence<int> IntS; +sequence<long> LongS; +sequence<float> FloatS; +sequence<double> DoubleS; +sequence<string> StringS; +sequence<MyEnum> MyEnumS; +sequence<MyClass*> MyClassS; + +sequence<ByteS> ByteSS; +sequence<BoolS> BoolSS; +sequence<ShortS> ShortSS; +sequence<IntS> IntSS; +sequence<LongS> LongSS; +sequence<FloatS> FloatSS; +sequence<DoubleS> DoubleSS; +sequence<StringS> StringSS; +sequence<MyEnumS> MyEnumSS; +sequence<MyClassS> MyClassSS; + +sequence<StringSS> StringSSS; + +struct MyStruct +{ + int i; + int j; +}; + +dictionary<byte, bool> ByteBoolD; +dictionary<short, int> ShortIntD; +dictionary<long, float> LongFloatD; +dictionary<string, string> StringStringD; +dictionary<string, MyEnum> StringMyEnumD; +dictionary<MyEnum, string> MyEnumStringD; +dictionary<MyStruct, MyEnum> MyStructMyEnumD; + +sequence<ByteBoolD> ByteBoolDS; +sequence<ShortIntD> ShortIntDS; +sequence<LongFloatD> LongFloatDS; +sequence<StringStringD> StringStringDS; +sequence<StringMyEnumD> StringMyEnumDS; +sequence<MyEnumStringD> MyEnumStringDS; +sequence<MyStructMyEnumD> MyStructMyEnumDS; + +dictionary<byte, ByteS> ByteByteSD; +dictionary<bool, BoolS> BoolBoolSD; +dictionary<short, ShortS> ShortShortSD; +dictionary<int, IntS> IntIntSD; +dictionary<long, LongS> LongLongSD; +dictionary<string, FloatS> StringFloatSD; +dictionary<string, DoubleS> StringDoubleSD; +dictionary<string, StringS> StringStringSD; +dictionary<MyEnum, MyEnumS> MyEnumMyEnumSD; + +class MyClass +{ + void shutdown(); + + void opVoid(); + + byte opByte(byte p1, byte p2, + out byte p3); + + bool opBool(bool p1, bool p2, + out bool p3); + + long opShortIntLong(short p1, int p2, long p3, + out short p4, out int p5, out long p6); + + double opFloatDouble(float p1, double p2, + out float p3, out double p4); + + string opString(string p1, string p2, + out string p3); + + MyEnum opMyEnum(MyEnum p1, out MyEnum p2); + + MyClass* opMyClass(MyClass* p1, out MyClass* p2, out MyClass* p3); + + Structure opStruct(Structure p1, Structure p2, + out Structure p3); + + ByteS opByteS(ByteS p1, ByteS p2, + out ByteS p3); + + BoolS opBoolS(BoolS p1, BoolS p2, + out BoolS p3); + + LongS opShortIntLongS(Test::ShortS p1, IntS p2, LongS p3, + out ::Test::ShortS p4, out IntS p5, out LongS p6); + + DoubleS opFloatDoubleS(FloatS p1, DoubleS p2, + out FloatS p3, out DoubleS p4); + + StringS opStringS(StringS p1, StringS p2, + out StringS p3); + + ByteSS opByteSS(ByteSS p1, ByteSS p2, + out ByteSS p3); + + BoolSS opBoolSS(BoolSS p1, BoolSS p2, + out BoolSS p3); + + LongSS opShortIntLongSS(ShortSS p1, IntSS p2, LongSS p3, + out ShortSS p4, out IntSS p5, out LongSS p6); + + DoubleSS opFloatDoubleSS(FloatSS p1, DoubleSS p2, + out FloatSS p3, out DoubleSS p4); + + StringSS opStringSS(StringSS p1, StringSS p2, + out StringSS p3); + + StringSSS opStringSSS(StringSSS p1, StringSSS p2, + out StringSSS p3); + + ByteBoolD opByteBoolD(ByteBoolD p1, ByteBoolD p2, + out ByteBoolD p3); + + ShortIntD opShortIntD(ShortIntD p1, ShortIntD p2, + out ShortIntD p3); + + LongFloatD opLongFloatD(LongFloatD p1, LongFloatD p2, + out LongFloatD p3); + + StringStringD opStringStringD(StringStringD p1, StringStringD p2, + out StringStringD p3); + + StringMyEnumD opStringMyEnumD(StringMyEnumD p1, StringMyEnumD p2, + out StringMyEnumD p3); + + MyEnumStringD opMyEnumStringD(MyEnumStringD p1, MyEnumStringD p2, + out MyEnumStringD p3); + + MyStructMyEnumD opMyStructMyEnumD(MyStructMyEnumD p1, MyStructMyEnumD p2, + out MyStructMyEnumD p3); + + ByteBoolDS opByteBoolDS(ByteBoolDS p1, ByteBoolDS p2, + out ByteBoolDS p3); + + ShortIntDS opShortIntDS(ShortIntDS p1, ShortIntDS p2, + out ShortIntDS p3); + + LongFloatDS opLongFloatDS(LongFloatDS p1, LongFloatDS p2, + out LongFloatDS p3); + + StringStringDS opStringStringDS(StringStringDS p1, StringStringDS p2, + out StringStringDS p3); + + StringMyEnumDS opStringMyEnumDS(StringMyEnumDS p1, StringMyEnumDS p2, + out StringMyEnumDS p3); + + MyEnumStringDS opMyEnumStringDS(MyEnumStringDS p1, MyEnumStringDS p2, + out MyEnumStringDS p3); + + MyStructMyEnumDS opMyStructMyEnumDS(MyStructMyEnumDS p1, MyStructMyEnumDS p2, + out MyStructMyEnumDS p3); + + ByteByteSD opByteByteSD(ByteByteSD p1, ByteByteSD p2, + out ByteByteSD p3); + + BoolBoolSD opBoolBoolSD(BoolBoolSD p1, BoolBoolSD p2, + out BoolBoolSD p3); + + ShortShortSD opShortShortSD(ShortShortSD p1, ShortShortSD p2, + out ShortShortSD p3); + + IntIntSD opIntIntSD(IntIntSD p1, IntIntSD p2, + out IntIntSD p3); + + LongLongSD opLongLongSD(LongLongSD p1, LongLongSD p2, + out LongLongSD p3); + + StringFloatSD opStringFloatSD(StringFloatSD p1, StringFloatSD p2, + out StringFloatSD p3); + + StringDoubleSD opStringDoubleSD(StringDoubleSD p1, StringDoubleSD p2, + out StringDoubleSD p3); + + StringStringSD opStringStringSD(StringStringSD p1, StringStringSD p2, + out StringStringSD p3); + + MyEnumMyEnumSD opMyEnumMyEnumSD(MyEnumMyEnumSD p1, MyEnumMyEnumSD p2, + out MyEnumMyEnumSD p3); + + IntS opIntS(IntS s); + + void opByteSOneway(ByteS s); + + int opByteSOnewayCallCount(); + + Ice::Context opContext(); + + void opDoubleMarshaling(double p1, DoubleS p2); + + idempotent void opIdempotent(); + + ["nonmutating"] idempotent void opNonmutating(); + + byte opByte1(byte opByte1); + short opShort1(short opShort1); + int opInt1(int opInt1); + long opLong1(long opLong1); + float opFloat1(float opFloat1); + double opDouble1(double opDouble1); + string opString1(string opString1); + StringS opStringS1(StringS opStringS1); + ByteBoolD opByteBoolD1(ByteBoolD opByteBoolD1); + StringS opStringS2(StringS stringS); + ByteBoolD opByteBoolD2(ByteBoolD byteBoolD); +}; + +struct MyStruct1 +{ + string tesT; // Same name as the enclosing module + MyClass myClass; // Same name as an already defined class + string myStruct1; // Same name as the enclosing struct +}; + +class MyClass1 +{ + string tesT; // Same name as the enclosing module + MyClass myClass; // Same name as an already defined class + string myClass1; // Same name as the enclosing class +}; + +class MyDerivedClass extends MyClass +{ + void opDerived(); + MyClass1 opMyClass1(MyClass1 opMyClass1); + MyStruct1 opMyStruct1(MyStruct1 opMyStruct1); +}; + +}; diff --git a/python/test/Ice/operations/TestAMD.ice b/python/test/Ice/operations/TestAMD.ice new file mode 100644 index 00000000000..772343fefbb --- /dev/null +++ b/python/test/Ice/operations/TestAMD.ice @@ -0,0 +1,270 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +enum MyEnum +{ + enum1, + enum2, + enum3 +}; + +class MyClass; + +struct AnotherStruct +{ + string s; +}; + +struct Structure +{ + MyClass* p; + MyEnum e; + AnotherStruct s; +}; + +sequence<byte> ByteS; +sequence<bool> BoolS; +sequence<short> ShortS; +sequence<int> IntS; +sequence<long> LongS; +sequence<float> FloatS; +sequence<double> DoubleS; +sequence<string> StringS; +sequence<MyEnum> MyEnumS; +sequence<MyClass*> MyClassS; + +sequence<ByteS> ByteSS; +sequence<BoolS> BoolSS; +sequence<ShortS> ShortSS; +sequence<IntS> IntSS; +sequence<LongS> LongSS; +sequence<FloatS> FloatSS; +sequence<DoubleS> DoubleSS; +sequence<StringS> StringSS; +sequence<MyEnumS> MyEnumSS; +sequence<MyClassS> MyClassSS; + +sequence<StringSS> StringSSS; + +struct MyStruct +{ + int i; + int j; +}; + +dictionary<byte, bool> ByteBoolD; +dictionary<short, int> ShortIntD; +dictionary<long, float> LongFloatD; +dictionary<string, string> StringStringD; +dictionary<string, MyEnum> StringMyEnumD; +dictionary<MyEnum, string> MyEnumStringD; +dictionary<MyStruct, MyEnum> MyStructMyEnumD; + +sequence<ByteBoolD> ByteBoolDS; +sequence<ShortIntD> ShortIntDS; +sequence<LongFloatD> LongFloatDS; +sequence<StringStringD> StringStringDS; +sequence<StringMyEnumD> StringMyEnumDS; +sequence<MyEnumStringD> MyEnumStringDS; +sequence<MyStructMyEnumD> MyStructMyEnumDS; + +dictionary<byte, ByteS> ByteByteSD; +dictionary<bool, BoolS> BoolBoolSD; +dictionary<short, ShortS> ShortShortSD; +dictionary<int, IntS> IntIntSD; +dictionary<long, LongS> LongLongSD; +dictionary<string, FloatS> StringFloatSD; +dictionary<string, DoubleS> StringDoubleSD; +dictionary<string, StringS> StringStringSD; +dictionary<MyEnum, MyEnumS> MyEnumMyEnumSD; + +["amd"] class MyClass +{ + void shutdown(); + + void opVoid(); + + byte opByte(byte p1, byte p2, + out byte p3); + + bool opBool(bool p1, bool p2, + out bool p3); + + long opShortIntLong(short p1, int p2, long p3, + out short p4, out int p5, out long p6); + + double opFloatDouble(float p1, double p2, + out float p3, out double p4); + + string opString(string p1, string p2, + out string p3); + + MyEnum opMyEnum(MyEnum p1, out MyEnum p2); + + MyClass* opMyClass(MyClass* p1, out MyClass* p2, out MyClass* p3); + + Structure opStruct(Structure p1, Structure p2, + out Structure p3); + + ByteS opByteS(ByteS p1, ByteS p2, + out ByteS p3); + + BoolS opBoolS(BoolS p1, BoolS p2, + out BoolS p3); + + LongS opShortIntLongS(Test::ShortS p1, IntS p2, LongS p3, + out ::Test::ShortS p4, out IntS p5, out LongS p6); + + DoubleS opFloatDoubleS(FloatS p1, DoubleS p2, + out FloatS p3, out DoubleS p4); + + StringS opStringS(StringS p1, StringS p2, + out StringS p3); + + ByteSS opByteSS(ByteSS p1, ByteSS p2, + out ByteSS p3); + + BoolSS opBoolSS(BoolSS p1, BoolSS p2, + out BoolSS p3); + + LongSS opShortIntLongSS(ShortSS p1, IntSS p2, LongSS p3, + out ShortSS p4, out IntSS p5, out LongSS p6); + + DoubleSS opFloatDoubleSS(FloatSS p1, DoubleSS p2, + out FloatSS p3, out DoubleSS p4); + + StringSS opStringSS(StringSS p1, StringSS p2, + out StringSS p3); + + StringSSS opStringSSS(StringSSS p1, StringSSS p2, + out StringSSS p3); + + ByteBoolD opByteBoolD(ByteBoolD p1, ByteBoolD p2, + out ByteBoolD p3); + + ShortIntD opShortIntD(ShortIntD p1, ShortIntD p2, + out ShortIntD p3); + + LongFloatD opLongFloatD(LongFloatD p1, LongFloatD p2, + out LongFloatD p3); + + StringStringD opStringStringD(StringStringD p1, StringStringD p2, + out StringStringD p3); + + StringMyEnumD opStringMyEnumD(StringMyEnumD p1, StringMyEnumD p2, + out StringMyEnumD p3); + + MyEnumStringD opMyEnumStringD(MyEnumStringD p1, MyEnumStringD p2, + out MyEnumStringD p3); + + MyStructMyEnumD opMyStructMyEnumD(MyStructMyEnumD p1, MyStructMyEnumD p2, + out MyStructMyEnumD p3); + + ByteBoolDS opByteBoolDS(ByteBoolDS p1, ByteBoolDS p2, + out ByteBoolDS p3); + + ShortIntDS opShortIntDS(ShortIntDS p1, ShortIntDS p2, + out ShortIntDS p3); + + LongFloatDS opLongFloatDS(LongFloatDS p1, LongFloatDS p2, + out LongFloatDS p3); + + StringStringDS opStringStringDS(StringStringDS p1, StringStringDS p2, + out StringStringDS p3); + + StringMyEnumDS opStringMyEnumDS(StringMyEnumDS p1, StringMyEnumDS p2, + out StringMyEnumDS p3); + + MyEnumStringDS opMyEnumStringDS(MyEnumStringDS p1, MyEnumStringDS p2, + out MyEnumStringDS p3); + + MyStructMyEnumDS opMyStructMyEnumDS(MyStructMyEnumDS p1, MyStructMyEnumDS p2, + out MyStructMyEnumDS p3); + + ByteByteSD opByteByteSD(ByteByteSD p1, ByteByteSD p2, + out ByteByteSD p3); + + BoolBoolSD opBoolBoolSD(BoolBoolSD p1, BoolBoolSD p2, + out BoolBoolSD p3); + + ShortShortSD opShortShortSD(ShortShortSD p1, ShortShortSD p2, + out ShortShortSD p3); + + IntIntSD opIntIntSD(IntIntSD p1, IntIntSD p2, + out IntIntSD p3); + + LongLongSD opLongLongSD(LongLongSD p1, LongLongSD p2, + out LongLongSD p3); + + StringFloatSD opStringFloatSD(StringFloatSD p1, StringFloatSD p2, + out StringFloatSD p3); + + StringDoubleSD opStringDoubleSD(StringDoubleSD p1, StringDoubleSD p2, + out StringDoubleSD p3); + + StringStringSD opStringStringSD(StringStringSD p1, StringStringSD p2, + out StringStringSD p3); + + MyEnumMyEnumSD opMyEnumMyEnumSD(MyEnumMyEnumSD p1, MyEnumMyEnumSD p2, + out MyEnumMyEnumSD p3); + + IntS opIntS(IntS s); + + void opByteSOneway(ByteS s); + + int opByteSOnewayCallCount(); + + StringStringD opContext(); + + void opDoubleMarshaling(double p1, DoubleS p2); + + idempotent void opIdempotent(); + + ["nonmutating"] idempotent void opNonmutating(); + + byte opByte1(byte opByte1); + short opShort1(short opShort1); + int opInt1(int opInt1); + long opLong1(long opLong1); + float opFloat1(float opFloat1); + double opDouble1(double opDouble1); + string opString1(string opString1); + StringS opStringS1(StringS opStringS1); + ByteBoolD opByteBoolD1(ByteBoolD opByteBoolD1); + StringS opStringS2(StringS stringS); + ByteBoolD opByteBoolD2(ByteBoolD byteBoolD); +}; + +struct MyStruct1 +{ + string tesT; // Same name as the enclosing module + MyClass myClass; // Same name as an already defined class + string myStruct1; // Same name as the enclosing struct +}; + +class MyClass1 +{ + string tesT; // Same name as the enclosing module + MyClass myClass; // Same name as an already defined class + string myClass1; // Same name as the enclosing class +}; + +["amd"] class MyDerivedClass extends MyClass +{ + void opDerived(); + MyClass1 opMyClass1(MyClass1 opMyClass1); + MyStruct1 opMyStruct1(MyStruct1 opMyStruct1); +}; + +}; diff --git a/python/test/Ice/operations/TestI.py b/python/test/Ice/operations/TestI.py new file mode 100644 index 00000000000..fac1fb228a8 --- /dev/null +++ b/python/test/Ice/operations/TestI.py @@ -0,0 +1,365 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class MyDerivedClassI(Test.MyDerivedClass): + def __init__(self): + self.lock = threading.Lock() + self.opByteSOnewayCount = 0 + + def ice_isA(self, id, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_isA(self, id, current) + + def ice_ping(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + Test.MyDerivedClass.ice_ping(self, current) + + def ice_ids(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_ids(self, current) + + def ice_id(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + return Test.MyDerivedClass.ice_id(self, current) + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def opVoid(self, current=None): + test(current.mode == Ice.OperationMode.Normal) + + def opByte(self, p1, p2, current=None): + return (p1, p1 ^ p2) + + def opBool(self, p1, p2, current=None): + return (p2, p1) + + def opShortIntLong(self, p1, p2, p3, current=None): + return (p3, p1, p2, p3) + + def opFloatDouble(self, p1, p2, current=None): + return (p2, p1, p2) + + def opString(self, p1, p2, current=None): + return (p1 + " " + p2, p2 + " " + p1) + + def opMyEnum(self, p1, current=None): + return (Test.MyEnum.enum3, p1) + + def opMyClass(self, p1, current=None): + return (Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.id)), p1, + Test.MyClassPrx.uncheckedCast(current.adapter.createProxy(current.adapter.getCommunicator().stringToIdentity("noSuchIdentity")))) + + def opStruct(self, p1, p2, current=None): + p1.s.s = "a new string" + return (p2, p1) + + def opByteS(self, p1, p2, current=None): + if sys.version_info[0] == 2: + # By default sequence<byte> maps to a string. + p3 = map(ord, p1) + p3.reverse() + r = map(ord, p1) + r.extend(map(ord, p2)) + else: + p3 = bytes(reversed(p1)) + r = p1 + p2 + return (r, p3) + + def opBoolS(self, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse(); + return (r, p3) + + def opShortIntLongS(self, p1, p2, p3, current=None): + p4 = p1[0:] + p5 = p2[0:] + p5.reverse() + p6 = p3[0:] + p6.extend(p3) + return (p3, p4, p5, p6) + + def opFloatDoubleS(self, p1, p2, current=None): + p3 = p1[0:] + p4 = p2[0:] + p4.reverse() + r = p2[0:] + r.extend(p1) + return (r, p3, p4) + + def opStringS(self, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse() + return (r, p3) + + def opByteSS(self, p1, p2, current=None): + p3 = p1[0:] + p3.reverse() + r = p1[0:] + r.extend(p2) + return (r, p3) + + def opBoolSS(self, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p1[0:] + r.reverse() + return (r, p3) + + def opShortIntLongSS(self, p1, p2, p3, current=None): + p4 = p1[0:] + p5 = p2[0:] + p5.reverse() + p6 = p3[0:] + p6.extend(p3) + return (p3, p4, p5, p6) + + def opFloatDoubleSS(self, p1, p2, current=None): + p3 = p1[0:] + p4 = p2[0:] + p4.reverse() + r = p2[0:] + r.extend(p2) + return (r, p3, p4) + + def opStringSS(self, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p2[0:] + r.reverse() + return (r, p3) + + def opStringSSS(self, p1, p2, current=None): + p3 = p1[0:] + p3.extend(p2) + r = p2[0:] + r.reverse() + return (r, p3) + + def opByteBoolD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opShortIntD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opLongFloatD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opStringStringD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opStringMyEnumD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opMyEnumStringD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opMyStructMyEnumD(self, p1, p2, current=None): + p3 = p1.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opByteBoolDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opShortIntDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opLongFloatDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opStringStringDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opStringMyEnumDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opMyEnumStringDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opMyStructMyEnumDS(self, p1, p2, current=None): + p3 = p2[0:] + p3.extend(p1) + r = p1[::-1] + return (r, p3) + + def opByteByteSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opBoolBoolSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opShortShortSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opIntIntSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opLongLongSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opStringFloatSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opStringDoubleSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opStringStringSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opMyEnumMyEnumSD(self, p1, p2, current=None): + p3 = p2.copy() + r = p1.copy() + r.update(p2) + return (r, p3) + + def opIntS(self, s, current=None): + return [-x for x in s] + + def opByteSOneway(self, s, current=None): + self.lock.acquire() + self.opByteSOnewayCount += 1 + self.lock.release() + + def opByteSOnewayCallCount(self, current=None): + self.lock.acquire() + count = self.opByteSOnewayCount + self.opByteSOnewayCount = 0 + self.lock.release() + return count + + def opContext(self, current=None): + return current.ctx + + def opDoubleMarshaling(self, p1, p2, current=None): + d = 1278312346.0 / 13.0; + test(p1 == d) + for i in p2: + test(i == d) + + def opIdempotent(self, current=None): + test(current.mode == Ice.OperationMode.Idempotent) + + def opNonmutating(self, current=None): + test(current.mode == Ice.OperationMode.Nonmutating) + + def opDerived(self, current=None): + pass + + def opByte1(self, value, current=None): + return value + + def opShort1(self, value, current=None): + return value + + def opInt1(self, value, current=None): + return value + + def opLong1(self, value, current=None): + return value + + def opFloat1(self, value, current=None): + return value + + def opDouble1(self, value, current=None): + return value + + def opString1(self, value, current=None): + return value + + def opStringS1(self, value, current=None): + return value + + def opByteBoolD1(self, value, current=None): + return value + + def opStringS2(self, value, current=None): + return value + + def opByteBoolD2(self, value, current=None): + return value + + def opMyClass1(self, value, current=None): + return value + + def opMyStruct1(self, value, current=None): + return value + +
\ No newline at end of file diff --git a/python/test/Ice/operations/Twoways.py b/python/test/Ice/operations/Twoways.py new file mode 100644 index 00000000000..1299a375d7a --- /dev/null +++ b/python/test/Ice/operations/Twoways.py @@ -0,0 +1,1334 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, math, Test, array, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def twoways(communicator, p): + # + # ice_ping + # + p.ice_ping() + + # + # ice_isA + # + test(p.ice_isA(Test.MyClass.ice_staticId())) + + # + # ice_ids + # + ids = p.ice_ids() + test(len(ids) == 3) + test(ids[0] == "::Ice::Object") + test(ids[1] == "::Test::MyClass") + test(ids[2] == "::Test::MyDerivedClass") + + # + # ice_id + # + test(p.ice_id() == Test.MyDerivedClass.ice_staticId()) + + # + # Prx ice_staticId + # + test(Test.MyClassPrx.ice_staticId() == Test.MyClass.ice_staticId()) + test(Test.MyDerivedClassPrx.ice_staticId() == Test.MyDerivedClass.ice_staticId()) + test(Ice.ObjectPrx.ice_staticId() == Ice.Object.ice_staticId()) + + # + # opVoid + # + p.opVoid() + + # + # opByte + # + r, b = p.opByte(0xff, 0x0f) + test(b == 0xf0) + test(r == 0xff) + + # + # opBool + # + r, b = p.opBool(True, False) + test(b) + test(not r) + + # + # opShortIntLong + # + r, s, i, l = p.opShortIntLong(10, 11, 12) + test(s == 10) + test(i == 11) + test(l == 12) + test(r == 12) + + r, s, i, l = p.opShortIntLong(-32768, -2147483648, -9223372036854775808) + test(s == -32768) + test(i == -2147483648) + test(l == -9223372036854775808) + test(r == -9223372036854775808) + + r, s, i, l = p.opShortIntLong(32767, 2147483647, 9223372036854775807) + test(s == 32767) + test(i == 2147483647) + test(l == 9223372036854775807) + test(r == 9223372036854775807) + + # + # opFloatDouble + # + r, f, d = p.opFloatDouble(3.14, 1.1E10) + test(f - 3.14 < 0.001) + test(d == 1.1E10) + test(r == 1.1E10) + + # + # Test invalid ranges for numbers + # + try: + r, b = p.opByte(0x01ff, 0x01ff) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(32767 + 1, 0, 0) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(-32768 -1, 0, 0) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(0, 2147483647 + 1, 0) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(0, -2147483648 - 1, 0) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(0, 0, 9223372036854775807 + 1) + test(False) + except ValueError: + pass + + try: + r, s, i, l = p.opShortIntLong(0, 0, -9223372036854775808 - 1) + test(False) + except ValueError: + pass + + r, f, d = p.opFloatDouble(3.402823466E38, 0.0) + r, f, d = p.opFloatDouble(-3.402823466E38, 0.0) + + try: + r, f, d = p.opFloatDouble(3.402823466E38*2, 0.0) + test(False) + except ValueError: + pass + + try: + r, f, d = p.opFloatDouble(-3.402823466E38*2, 0.0) + test(False) + except ValueError: + pass + + # + # opString + # + r, s = p.opString("hello", "world") + test(s == "world hello") + test(r == "hello world") + if sys.version_info[0] == 2: + r, s = p.opString(unicode("hello"), unicode("world")) + test(s == "world hello") + test(r == "hello world") + + # + # opMyEnum + # + r, e = p.opMyEnum(Test.MyEnum.enum2) + test(e == Test.MyEnum.enum2) + test(r == Test.MyEnum.enum3) + + # + # opMyClass + # + r, c1, c2 = p.opMyClass(p) + test(Ice.proxyIdentityAndFacetEqual(c1, p)) + test(not Ice.proxyIdentityAndFacetEqual(c2, p)) + test(Ice.proxyIdentityAndFacetEqual(r, p)) + test(c1.ice_getIdentity() == communicator.stringToIdentity("test")) + test(c2.ice_getIdentity() == communicator.stringToIdentity("noSuchIdentity")) + test(r.ice_getIdentity() == communicator.stringToIdentity("test")) + r.opVoid() + c1.opVoid() + try: + c2.opVoid() + test(False) + except Ice.ObjectNotExistException: + pass + + r, c1, c2 = p.opMyClass(None) + test(not c1) + test(c2) + test(Ice.proxyIdentityAndFacetEqual(r, p)) + r.opVoid() + + # + # opStruct + # + si1 = Test.Structure() + si1.p = p + si1.e = Test.MyEnum.enum3 + si1.s = Test.AnotherStruct() + si1.s.s = "abc" + si2 = Test.Structure() + si2.p = None + si2.e = Test.MyEnum.enum2 + si2.s = Test.AnotherStruct() + si2.s.s = "def" + + rso, so = p.opStruct(si1, si2) + test(not rso.p) + test(rso.e == Test.MyEnum.enum2) + test(rso.s.s == "def") + test(so.p == p) + test(so.e == Test.MyEnum.enum3) + test(so.s.s == "a new string") + so.p.opVoid() + + # Test marshalling of null structs and structs with null members. + si1 = Test.Structure() + si2 = None + + rso, so = p.opStruct(si1, si2) + test(rso.p is None) + test(rso.e == Test.MyEnum.enum1) + test(rso.s.s == "") + test(so.p is None) + test(so.e == Test.MyEnum.enum1) + test(so.s.s == "a new string") + + # + # opByteS + # + bsi1 = (0x01, 0x11, 0x12, 0x22) + bsi2 = (0xf1, 0xf2, 0xf3, 0xf4) + + rso, bso = p.opByteS(bsi1, bsi2) + test(len(bso) == 4) + test(len(rso) == 8) + if sys.version_info[0] == 2: + test(bso[0] == '\x22') + test(bso[1] == '\x12') + test(bso[2] == '\x11') + test(bso[3] == '\x01') + test(rso[0] == '\x01') + test(rso[1] == '\x11') + test(rso[2] == '\x12') + test(rso[3] == '\x22') + test(rso[4] == '\xf1') + test(rso[5] == '\xf2') + test(rso[6] == '\xf3') + test(rso[7] == '\xf4') + else: + test(bso[0] == 0x22) + test(bso[1] == 0x12) + test(bso[2] == 0x11) + test(bso[3] == 0x01) + test(rso[0] == 0x01) + test(rso[1] == 0x11) + test(rso[2] == 0x12) + test(rso[3] == 0x22) + test(rso[4] == 0xf1) + test(rso[5] == 0xf2) + test(rso[6] == 0xf3) + test(rso[7] == 0xf4) + + # + # opByteS (array) + # + bsi1 = array.array('B') + bsi1.fromlist([0x01, 0x11, 0x12, 0x22]) + bsi2 = array.array('B') + bsi2.fromlist([0xf1, 0xf2, 0xf3, 0xf4]) + + rso, bso = p.opByteS(bsi1, bsi2) + test(len(bso) == 4) + test(len(rso) == 8) + if sys.version_info[0] == 2: + test(bso[0] == '\x22') + test(bso[1] == '\x12') + test(bso[2] == '\x11') + test(bso[3] == '\x01') + test(rso[0] == '\x01') + test(rso[1] == '\x11') + test(rso[2] == '\x12') + test(rso[3] == '\x22') + test(rso[4] == '\xf1') + test(rso[5] == '\xf2') + test(rso[6] == '\xf3') + test(rso[7] == '\xf4') + else: + test(bso[0] == 0x22) + test(bso[1] == 0x12) + test(bso[2] == 0x11) + test(bso[3] == 0x01) + test(rso[0] == 0x01) + test(rso[1] == 0x11) + test(rso[2] == 0x12) + test(rso[3] == 0x22) + test(rso[4] == 0xf1) + test(rso[5] == 0xf2) + test(rso[6] == 0xf3) + test(rso[7] == 0xf4) + + # + # opBoolS + # + bsi1 = (True, True, False) + bsi2 = (False,) + + rso, bso = p.opBoolS(bsi1, bsi2) + test(len(bso) == 4) + test(bso[0]) + test(bso[1]) + test(not bso[2]) + test(not bso[3]) + test(len(rso) == 3) + test(not rso[0]) + test(rso[1]) + test(rso[2]) + + # + # opBoolS (array) + # + bsi1 = array.array('B') + bsi1.fromlist([1, 1, 0]) + bsi2 = array.array('B') + bsi2.fromlist([0]) + + rso, bso = p.opBoolS(bsi1, bsi2) + test(len(bso) == 4) + test(bso[0]) + test(bso[1]) + test(not bso[2]) + test(not bso[3]) + test(len(rso) == 3) + test(not rso[0]) + test(rso[1]) + test(rso[2]) + + # + # opShortIntLongS + # + ssi = (1, 2, 3) + isi = (5, 6, 7, 8) + lsi = (10, 30, 20) + + rso, sso, iso, lso = p.opShortIntLongS(ssi, isi, lsi) + test(len(sso) == 3) + test(sso[0] == 1) + test(sso[1] == 2) + test(sso[2] == 3) + test(len(iso) == 4) + test(iso[0] == 8) + test(iso[1] == 7) + test(iso[2] == 6) + test(iso[3] == 5) + test(len(lso) == 6) + test(lso[0] == 10) + test(lso[1] == 30) + test(lso[2] == 20) + test(lso[3] == 10) + test(lso[4] == 30) + test(lso[5] == 20) + test(len(rso) == 3) + test(rso[0] == 10) + test(rso[1] == 30) + test(rso[2] == 20) + + # + # opShortIntLongS (array) + # + ssi = array.array('h') + ssi.fromlist([1, 2, 3]) + isi = array.array('i') + isi.fromlist([5, 6, 7, 8]) + lsi = (10, 30, 20) # Can't store Ice::Long in an array. + + rso, sso, iso, lso = p.opShortIntLongS(ssi, isi, lsi) + test(len(sso) == 3) + test(sso[0] == 1) + test(sso[1] == 2) + test(sso[2] == 3) + test(len(iso) == 4) + test(iso[0] == 8) + test(iso[1] == 7) + test(iso[2] == 6) + test(iso[3] == 5) + test(len(lso) == 6) + test(lso[0] == 10) + test(lso[1] == 30) + test(lso[2] == 20) + test(lso[3] == 10) + test(lso[4] == 30) + test(lso[5] == 20) + test(len(rso) == 3) + test(rso[0] == 10) + test(rso[1] == 30) + test(rso[2] == 20) + + # + # opFloatDoubleS + # + fsi = (3.14, 1.11) + dsi = (1.1E10, 1.2E10, 1.3E10) + + rso, fso, dso = p.opFloatDoubleS(fsi, dsi) + test(len(fso) == 2) + test(fso[0] - 3.14 < 0.001) + test(fso[1] - 1.11 < 0.001) + test(len(dso) == 3) + test(dso[0] == 1.3E10) + test(dso[1] == 1.2E10) + test(dso[2] == 1.1E10) + test(len(rso) == 5) + test(rso[0] == 1.1E10) + test(rso[1] == 1.2E10) + test(rso[2] == 1.3E10) + test(rso[3] - 3.14 < 0.001) + test(rso[4] - 1.11 < 0.001) + + # + # opFloatDoubleS (array) + # + fsi = array.array('f') + fsi.fromlist([3.14, 1.11]) + dsi = array.array('d') + dsi.fromlist([1.1E10, 1.2E10, 1.3E10]) + + rso, fso, dso = p.opFloatDoubleS(fsi, dsi) + test(len(fso) == 2) + test(fso[0] - 3.14 < 0.001) + test(fso[1] - 1.11 < 0.001) + test(len(dso) == 3) + test(dso[0] == 1.3E10) + test(dso[1] == 1.2E10) + test(dso[2] == 1.1E10) + test(len(rso) == 5) + test(rso[0] == 1.1E10) + test(rso[1] == 1.2E10) + test(rso[2] == 1.3E10) + test(rso[3] - 3.14 < 0.001) + test(rso[4] - 1.11 < 0.001) + + # + # opStringS + # + ssi1 = ('abc', 'de', 'fghi') + ssi2 = ('xyz',) + + rso, sso = p.opStringS(ssi1, ssi2) + test(len(sso) == 4) + test(sso[0] == "abc") + test(sso[1] == "de") + test(sso[2] == "fghi") + test(sso[3] == "xyz") + test(len(rso) == 3) + test(rso[0] == "fghi") + test(rso[1] == "de") + test(rso[2] == "abc") + + # + # opByteSS + # + bsi1 = ((0x01, 0x11, 0x12), (0xff,)) + bsi2 = ((0x0e,), (0xf2, 0xf1)) + + rso, bso = p.opByteSS(bsi1, bsi2) + test(len(bso) == 2) + test(len(bso[0]) == 1) + test(len(bso[1]) == 3) + test(len(rso) == 4) + test(len(rso[0]) == 3) + test(len(rso[1]) == 1) + test(len(rso[2]) == 1) + test(len(rso[3]) == 2) + if sys.version_info[0] == 2: + test(bso[0][0] == '\xff') + test(bso[1][0] == '\x01') + test(bso[1][1] == '\x11') + test(bso[1][2] == '\x12') + test(rso[0][0] == '\x01') + test(rso[0][1] == '\x11') + test(rso[0][2] == '\x12') + test(rso[1][0] == '\xff') + test(rso[2][0] == '\x0e') + test(rso[3][0] == '\xf2') + test(rso[3][1] == '\xf1') + else: + test(bso[0][0] == 0xff) + test(bso[1][0] == 0x01) + test(bso[1][1] == 0x11) + test(bso[1][2] == 0x12) + test(rso[0][0] == 0x01) + test(rso[0][1] == 0x11) + test(rso[0][2] == 0x12) + test(rso[1][0] == 0xff) + test(rso[2][0] == 0x0e) + test(rso[3][0] == 0xf2) + test(rso[3][1] == 0xf1) + + # + # opBoolSS + # + bsi1 = ((True,), (False,), (True, True),) + bsi2 = ((False, False, True),) + + rso, bso = p.opBoolSS(bsi1, bsi2) + test(len(bso) == 4) + test(len(bso[0]) == 1) + test(bso[0][0]) + test(len(bso[1]) == 1) + test(not bso[1][0]) + test(len(bso[2]) == 2) + test(bso[2][0]) + test(bso[2][1]) + test(len(bso[3]) == 3) + test(not bso[3][0]) + test(not bso[3][1]) + test(bso[3][2]) + test(len(rso) == 3) + test(len(rso[0]) == 2) + test(rso[0][0]) + test(rso[0][1]) + test(len(rso[1]) == 1) + test(not rso[1][0]) + test(len(rso[2]) == 1) + test(rso[2][0]) + + # + # opShortIntLongSS + # + ssi = ((1,2,5), (13,), ()) + isi = ((24, 98), (42,)) + lsi = ((496, 1729),) + + rso, sso, iso, lso = p.opShortIntLongSS(ssi, isi, lsi) + test(len(rso) == 1) + test(len(rso[0]) == 2) + test(rso[0][0] == 496) + test(rso[0][1] == 1729) + test(len(sso) == 3) + test(len(sso[0]) == 3) + test(sso[0][0] == 1) + test(sso[0][1] == 2) + test(sso[0][2] == 5) + test(len(sso[1]) == 1) + test(sso[1][0] == 13) + test(len(sso[2]) == 0) + test(len(iso) == 2) + test(len(iso[0]) == 1) + test(iso[0][0] == 42) + test(len(iso[1]) == 2) + test(iso[1][0] == 24) + test(iso[1][1] == 98) + test(len(lso) == 2) + test(len(lso[0]) == 2) + test(lso[0][0] == 496) + test(lso[0][1] == 1729) + test(len(lso[1]) == 2) + test(lso[1][0] == 496) + test(lso[1][1] == 1729) + + # + # opFloatDoubleSS + # + fsi = ((3.14,), (1.11,), ()) + dsi = ((1.1E10, 1.2E10, 1.3E10),) + + rso, fso, dso = p.opFloatDoubleSS(fsi, dsi) + test(len(fso) == 3) + test(len(fso[0]) == 1) + test(fso[0][0] - 3.14 < 0.001) + test(len(fso[1]) == 1) + test(fso[1][0] - 1.11 < 0.001) + test(len(fso[2]) == 0) + test(len(dso) == 1) + test(len(dso[0]) == 3) + test(dso[0][0] == 1.1E10) + test(dso[0][1] == 1.2E10) + test(dso[0][2] == 1.3E10) + test(len(rso) == 2) + test(len(rso[0]) == 3) + test(rso[0][0] == 1.1E10) + test(rso[0][1] == 1.2E10) + test(rso[0][2] == 1.3E10) + test(len(rso[1]) == 3) + test(rso[1][0] == 1.1E10) + test(rso[1][1] == 1.2E10) + test(rso[1][2] == 1.3E10) + + # + # opStringSS + # + ssi1 = (('abc',), ('de', 'fghi')) + ssi2 = ((), (), ('xyz',)) + + rso, sso = p.opStringSS(ssi1, ssi2) + test(len(sso) == 5) + test(len(sso[0]) == 1) + test(sso[0][0] == "abc") + test(len(sso[1]) == 2) + test(sso[1][0] == "de") + test(sso[1][1] == "fghi") + test(len(sso[2]) == 0) + test(len(sso[3]) == 0) + test(len(sso[4]) == 1) + test(sso[4][0] == "xyz") + test(len(rso) == 3) + test(len(rso[0]) == 1) + test(rso[0][0] == "xyz") + test(len(rso[1]) == 0) + test(len(rso[2]) == 0) + + # + # opStringSSS + # + sssi1 = ((('abc', 'de'), ('xyz',)), (('hello',),)) + sssi2 = ((('', ''), ('abcd',)), (('',),), ()) + + rsso, ssso = p.opStringSSS(sssi1, sssi2) + test(len(ssso) == 5) + test(len(ssso[0]) == 2) + test(len(ssso[0][0]) == 2) + test(len(ssso[0][1]) == 1) + test(len(ssso[1]) == 1) + test(len(ssso[1][0]) == 1) + test(len(ssso[2]) == 2) + test(len(ssso[2][0]) == 2) + test(len(ssso[2][1]) == 1) + test(len(ssso[3]) == 1) + test(len(ssso[3][0]) == 1) + test(len(ssso[4]) == 0) + test(ssso[0][0][0] == "abc") + test(ssso[0][0][1] == "de") + test(ssso[0][1][0] == "xyz") + test(ssso[1][0][0] == "hello") + test(ssso[2][0][0] == "") + test(ssso[2][0][1] == "") + test(ssso[2][1][0] == "abcd") + test(ssso[3][0][0] == "") + + test(len(rsso) == 3) + test(len(rsso[0]) == 0) + test(len(rsso[1]) == 1) + test(len(rsso[1][0]) == 1) + test(len(rsso[2]) == 2) + test(len(rsso[2][0]) == 2) + test(len(rsso[2][1]) == 1) + test(rsso[1][0][0] == "") + test(rsso[2][0][0] == "") + test(rsso[2][0][1] == "") + test(rsso[2][1][0] == "abcd") + + # + # opByteBoolD + # + di1 = {10: True, 100: False} + di2 = {10: True, 11: False, 101: True} + + ro, do = p.opByteBoolD(di1, di2) + + test(do == di1) + test(len(ro) == 4) + test(ro[10]) + test(not ro[11]) + test(not ro[100]) + test(ro[101]) + + # + # opShortIntD + # + di1 = {110: -1, 1100: 123123} + di2 = {110: -1, 111: -100, 1101: 0} + + ro, do = p.opShortIntD(di1, di2) + + test(do == di1) + test(len(ro) == 4) + test(ro[110] == -1) + test(ro[111] == -100) + test(ro[1100] == 123123) + test(ro[1101] == 0) + + # + # opLongFloatD + # + di1 = {999999110: -1.1, 999999111: 123123.2} + di2 = {999999110: -1.1, 999999120: -100.4, 999999130: 0.5} + + ro, do = p.opLongFloatD(di1, di2) + + for k in do: + test(math.fabs(do[k] - di1[k]) < 0.01) + test(len(ro) == 4) + test(ro[999999110] - -1.1 < 0.01) + test(ro[999999120] - -100.4 < 0.01) + test(ro[999999111] - 123123.2 < 0.01) + test(ro[999999130] - 0.5 < 0.01) + + # + # opStringStringD + # + di1 = {'foo': 'abc -1.1', 'bar': 'abc 123123.2'} + di2 = {'foo': 'abc -1.1', 'FOO': 'abc -100.4', 'BAR': 'abc 0.5'} + + ro, do = p.opStringStringD(di1, di2) + + test(do == di1) + test(len(ro) == 4) + test(ro["foo"] == "abc -1.1") + test(ro["FOO"] == "abc -100.4") + test(ro["bar"] == "abc 123123.2") + test(ro["BAR"] == "abc 0.5") + + # + # opStringMyEnumD + # + di1 = {'abc': Test.MyEnum.enum1, '': Test.MyEnum.enum2} + di2 = {'abc': Test.MyEnum.enum1, 'qwerty': Test.MyEnum.enum3, 'Hello!!': Test.MyEnum.enum2} + + ro, do = p.opStringMyEnumD(di1, di2) + + test(do == di1) + test(len(ro) == 4) + test(ro["abc"] == Test.MyEnum.enum1) + test(ro["qwerty"] == Test.MyEnum.enum3) + test(ro[""] == Test.MyEnum.enum2) + test(ro["Hello!!"] == Test.MyEnum.enum2) + + # + # opMyEnumStringD + # + di1 = {Test.MyEnum.enum1: 'abc'} + di2 = {Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'} + + ro, do = p.opMyEnumStringD(di1, di2) + + test(do == di1) + test(len(ro) == 3) + test(ro[Test.MyEnum.enum1] == "abc") + test(ro[Test.MyEnum.enum2] == "Hello!!") + test(ro[Test.MyEnum.enum3] == "qwerty") + + # + # opMyStructMyEnumD + # + s11 = Test.MyStruct() + s11.i = 1 + s11.j = 1 + s12 = Test.MyStruct() + s12.i = 1 + s12.j = 2 + s22 = Test.MyStruct() + s22.i = 2 + s22.j = 2 + s23 = Test.MyStruct() + s23.i = 2 + s23.j = 3 + di1 = {s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2} + di2 = {s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2} + + ro, do = p.opMyStructMyEnumD(di1, di2) + + test(do == di1) + test(len(ro) == 4) + test(ro[s11] == Test.MyEnum.enum1) + test(ro[s12] == Test.MyEnum.enum2) + test(ro[s22] == Test.MyEnum.enum3) + test(ro[s23] == Test.MyEnum.enum2) + + # + # opByteBoolDS + # + dsi1 = ({ 10: True, 100: False }, { 10: True, 11: False, 101: True }) + dsi2 = ({ 100: False, 101: False },) + + ro, do = p.opByteBoolDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][10]) + test(not ro[0][11]) + test(ro[0][101]) + test(len(ro[1]) == 2) + test(ro[1][10]) + test(not ro[1][100]) + test(len(do) == 3) + test(len(do[0]) == 2) + test(not do[0][100]) + test(not do[0][101]) + test(len(do[1]) == 2) + test(do[1][10]) + test(not do[1][100]) + test(len(do[2]) == 3) + test(do[2][10]) + test(not do[2][11]) + test(do[2][101]) + + # + # opShortIntDS + # + dsi1 = ({ 110: -1, 1100: 123123 }, { 110: -1, 111: -100, 1101: 0 }) + dsi2 = ({ 100: -1001 },) + + ro, do = p.opShortIntDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][110] == -1) + test(ro[0][111] == -100) + test(ro[0][1101] == 0) + test(len(ro[1]) == 2) + test(ro[1][110] == -1) + test(ro[1][1100] == 123123) + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][100] == -1001) + test(len(do[1]) == 2) + test(do[1][110] == -1) + test(do[1][1100] == 123123) + test(len(do[2]) == 3) + test(do[2][110] == -1) + test(do[2][111] == -100) + test(do[2][1101] == 0) + + # + # opLongFloatDS + # + dsi1 = ({ 999999110: -1.1, 999999111: 123123.2 }, { 999999110: -1.1, 999999120: -100.4, 999999130: 0.5 }) + dsi2 = ({ 999999140: 3.14 },) + + ro, do = p.opLongFloatDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][999999110] - -1.1 < 0.01) + test(ro[0][999999120] - -100.4 < 0.01) + test(ro[0][999999130] - 0.5 < 0.01) + test(len(ro[1]) == 2) + test(ro[1][999999110] - -1.1 < 0.01) + test(ro[1][999999111] - 123123.2 < 0.01) + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][999999140] - 3.14 < 0.01) + test(len(do[1]) == 2) + test(do[1][999999110] - -1.1 < 0.01) + test(do[1][999999111] - 123123.2 < 0.01) + test(len(do[2]) == 3) + test(do[2][999999110] - -1.1 < 0.01) + test(do[2][999999120] - -100.4 < 0.01) + test(do[2][999999130] - 0.5 < 0.01) + + # + # opStringStringDS + # + + dsi1 = ({ "foo": "abc -1.1", "bar": "abc 123123.2" }, { "foo": "abc -1.1", "FOO": "abc -100.4", "BAR": "abc 0.5" }) + dsi2 = ({ "f00": "ABC -3.14" },) + + ro, do = p.opStringStringDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0]["foo"] == "abc -1.1") + test(ro[0]["FOO"] == "abc -100.4") + test(ro[0]["BAR"] == "abc 0.5") + test(len(ro[1]) == 2) + test(ro[1]["foo"] == "abc -1.1") + test(ro[1]["bar"] == "abc 123123.2") + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0]["f00"] == "ABC -3.14") + test(len(do[1]) == 2) + test(do[1]["foo"] == "abc -1.1") + test(do[1]["bar"] == "abc 123123.2") + test(len(do[2]) == 3) + test(do[2]["foo"] == "abc -1.1") + test(do[2]["FOO"] == "abc -100.4") + test(do[2]["BAR"] == "abc 0.5") + + # + # opStringMyEnumDS + # + dsi1 = ( + { "abc": Test.MyEnum.enum1, "": Test.MyEnum.enum2 }, + { "abc": Test.MyEnum.enum1, "qwerty": Test.MyEnum.enum3, "Hello!!": Test.MyEnum.enum2 } + ) + + dsi2 = ({ "Goodbye": Test.MyEnum.enum1 },) + + ro, do = p.opStringMyEnumDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0]["abc"] == Test.MyEnum.enum1) + test(ro[0]["qwerty"] == Test.MyEnum.enum3) + test(ro[0]["Hello!!"] == Test.MyEnum.enum2) + test(len(ro[1]) == 2) + test(ro[1]["abc"] == Test.MyEnum.enum1) + test(ro[1][""] == Test.MyEnum.enum2) + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0]["Goodbye"] == Test.MyEnum.enum1) + test(len(do[1]) == 2) + test(do[1]["abc"] == Test.MyEnum.enum1) + test(do[1][""] == Test.MyEnum.enum2) + test(len(do[2]) == 3) + test(do[2]["abc"] == Test.MyEnum.enum1) + test(do[2]["qwerty"] == Test.MyEnum.enum3) + test(do[2]["Hello!!"] == Test.MyEnum.enum2) + + # + # opMyEnumStringDS + # + dsi1 = ({ Test.MyEnum.enum1: 'abc' }, { Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'}) + dsi2 = ({ Test.MyEnum.enum1: 'Goodbye' },) + + ro, do = p.opMyEnumStringDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 2) + test(ro[0][Test.MyEnum.enum2] == "Hello!!") + test(ro[0][Test.MyEnum.enum3] == "qwerty") + test(len(ro[1]) == 1) + test(ro[1][Test.MyEnum.enum1] == "abc") + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][Test.MyEnum.enum1] == "Goodbye") + test(len(do[1]) == 1) + test(do[1][Test.MyEnum.enum1] == "abc") + test(len(do[2]) == 2) + test(do[2][Test.MyEnum.enum2] == "Hello!!") + test(do[2][Test.MyEnum.enum3] == "qwerty") + + # + # opMyStructMyEnumDS + # + s11 = Test.MyStruct(1, 1) + s12 = Test.MyStruct(1, 2) + + s22 = Test.MyStruct(2, 2) + s23 = Test.MyStruct(2, 3) + + dsi1 = ( + { s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2 }, + { s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2 } + ) + dsi2 = ({ s23: Test.MyEnum.enum3 },) + + ro, do = p.opMyStructMyEnumDS(dsi1, dsi2) + + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][s11] == Test.MyEnum.enum1) + test(ro[0][s22] == Test.MyEnum.enum3) + test(ro[0][s23] == Test.MyEnum.enum2) + test(len(ro[1]) == 2) + test(ro[1][s11] == Test.MyEnum.enum1) + test(ro[1][s12] == Test.MyEnum.enum2) + + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][s23] == Test.MyEnum.enum3) + test(len(do[1]) == 2) + test(do[1][s11] == Test.MyEnum.enum1) + test(do[1][s12] == Test.MyEnum.enum2) + test(len(do[2]) == 3) + test(do[2][s11] == Test.MyEnum.enum1) + test(do[2][s22] == Test.MyEnum.enum3) + test(do[2][s23] == Test.MyEnum.enum2) + + # + #opByteByteSD + # + sdi1 = { 0x01: (0x01, 0x11), 0x22: (0x12,) } + sdi2 = { 0xf1: (0xf2, 0xf3) } + + ro, do = p.opByteByteSD(sdi1, sdi2) + + if sys.version_info[0] == 2: + test(len(do) == 1) + test(len(do[0xf1]) == 2) + test(do[0xf1][0] == '\xf2') + test(do[0xf1][1] == '\xf3') + test(len(ro) == 3) + test(len(ro[0x01]) == 2) + test(ro[0x01][0] == '\x01') + test(ro[0x01][1] == '\x11') + test(len(ro[0x22]) == 1) + test(ro[0x22][0] == '\x12') + test(len(ro[0xf1]) == 2) + test(ro[0xf1][0] == '\xf2') + test(ro[0xf1][1] == '\xf3') + else: + test(len(do) == 1) + test(len(do[0xf1]) == 2) + test(do[0xf1][0] == 0xf2) + test(do[0xf1][1] == 0xf3) + test(len(ro) == 3) + test(len(ro[0x01]) == 2) + test(ro[0x01][0] == 0x01) + test(ro[0x01][1] == 0x11) + test(len(ro[0x22]) == 1) + test(ro[0x22][0] == 0x12) + test(len(ro[0xf1]) == 2) + test(ro[0xf1][0] == 0xf2) + test(ro[0xf1][1] == 0xf3) + + # + # opBoolBoolSD + # + sdi1 = { False: (True, False), True: (False, True, True) } + sdi2 = { False: (True, False) } + + ro, do = p.opBoolBoolSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do[False]) == 2) + test(do[False][0]) + test(not do[False][1]) + test(len(ro) == 2) + test(len(ro[False]) == 2) + test(ro[False][0]) + test(not ro[False][1]) + test(len(ro[True]) == 3) + test(not ro[True][0]) + test(ro[True][1]) + test(ro[True][2]) + + # + # opShortShortSD + # + sdi1 = { 1: (1, 2, 3), 2: (4, 5) } + sdi2 = { 4: (6, 7) } + + ro, do = p.opShortShortSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do[4]) == 2) + test(do[4][0] == 6) + test(do[4][1] == 7) + test(len(ro) == 3) + test(len(ro[1]) == 3) + test(ro[1][0] == 1) + test(ro[1][1] == 2) + test(ro[1][2] == 3) + test(len(ro[2]) == 2) + test(ro[2][0] == 4) + test(ro[2][1] == 5) + test(len(ro[4]) == 2) + test(ro[4][0] == 6) + test(ro[4][1] == 7) + + # + # opIntIntSD + # + sdi1 = { 100: (100, 200, 300), 200: (400, 500) } + sdi2 = { 400: (600, 700) } + + ro, do = p.opIntIntSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do[400]) == 2) + test(do[400][0] == 600) + test(do[400][1] == 700) + test(len(ro) == 3) + test(len(ro[100]) == 3) + test(ro[100][0] == 100) + test(ro[100][1] == 200) + test(ro[100][2] == 300) + test(len(ro[200]) == 2) + test(ro[200][0] == 400) + test(ro[200][1] == 500) + test(len(ro[400]) == 2) + test(ro[400][0] == 600) + test(ro[400][1] == 700) + + # + # opLongLongSD + # + sdi1 = { 999999990: (999999110, 999999111, 999999110), 999999991: (999999120, 999999130) } + sdi2 = { 999999992: (999999110, 999999120) } + + ro, do = p.opLongLongSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do[999999992]) == 2) + test(do[999999992][0] == 999999110) + test(do[999999992][1] == 999999120) + test(len(ro) == 3) + test(len(ro[999999990]) == 3) + test(ro[999999990][0] == 999999110) + test(ro[999999990][1] == 999999111) + test(ro[999999990][2] == 999999110) + test(len(ro[999999991]) == 2) + test(ro[999999991][0] == 999999120) + test(ro[999999991][1] == 999999130) + test(len(ro[999999992]) == 2) + test(ro[999999992][0] == 999999110) + test(ro[999999992][1] == 999999120) + + # + # opStringFloatSD + # + sdi1 = { "abc": (-1.1, 123123.2, 100.0), "ABC": (42.24, -1.61) } + sdi2 = { "aBc": (-3.14, 3.14) } + + ro, do = p.opStringFloatSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do["aBc"]) == 2) + test(do["aBc"][0] - -3.14 < 0.01) + test(do["aBc"][1] - 3.14 < 0.01) + + test(len(ro) == 3) + test(len(ro["abc"]) == 3) + test(ro["abc"][0] - -1.1 < 0.01) + test(ro["abc"][1] - 123123.2 < 0.01) + test(ro["abc"][2] - 100.0 < 0.01) + test(len(ro["ABC"]) == 2) + test(ro["ABC"][0] - 42.24 < 0.01) + test(ro["ABC"][1] - -1.61 < 0.01) + test(len(ro["aBc"]) == 2) + test(ro["aBc"][0] - -3.14 < 0.01) + test(ro["aBc"][1] - 3.14 < 0.01) + + # + # opStringDoubleSD + # + sdi1 = { "Hello!!": (1.1E10, 1.2E10, 1.3E10), "Goodbye": (1.4E10, 1.5E10) } + sdi2 = { "": (1.6E10, 1.7E10) } + + ro, do = p.opStringDoubleSD(sdi1, sdi2); + + test(len(do) == 1) + test(len(do[""]) == 2) + test(do[""][0] == 1.6E10) + test(do[""][1] == 1.7E10) + test(len(ro) == 3) + test(len(ro["Hello!!"]) == 3) + test(ro["Hello!!"][0] == 1.1E10) + test(ro["Hello!!"][1] == 1.2E10) + test(ro["Hello!!"][2] == 1.3E10) + test(len(ro["Goodbye"]) == 2) + test(ro["Goodbye"][0] == 1.4E10) + test(ro["Goodbye"][1] == 1.5E10) + test(len(ro[""]) == 2) + test(ro[""][0] == 1.6E10) + test(ro[""][1] == 1.7E10) + + # + # opStringStringSD + # + sdi1 = { "abc": ("abc", "de", "fghi") , "def": ("xyz", "or") } + sdi2 = { "ghi": ("and", "xor") } + + ro, do = p.opStringStringSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do["ghi"]) == 2) + test(do["ghi"][0] == "and") + test(do["ghi"][1] == "xor") + test(len(ro) == 3) + test(len(ro["abc"]) == 3) + test(ro["abc"][0] == "abc") + test(ro["abc"][1] == "de") + test(ro["abc"][2] == "fghi") + test(len(ro["def"]) == 2) + test(ro["def"][0] == "xyz") + test(ro["def"][1] == "or") + test(len(ro["ghi"]) == 2) + test(ro["ghi"][0] == "and") + test(ro["ghi"][1] == "xor") + + # + # opMyEnumMyEnumSD + # + sdi1 = { + Test.MyEnum.enum3: (Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2), + Test.MyEnum.enum2: (Test.MyEnum.enum1, Test.MyEnum.enum2) + } + sdi2 = { Test.MyEnum.enum1: (Test.MyEnum.enum3, Test.MyEnum.enum3) } + + ro, do = p.opMyEnumMyEnumSD(sdi1, sdi2) + + test(len(do) == 1) + test(len(do[Test.MyEnum.enum1]) == 2) + test(do[Test.MyEnum.enum1][0] == Test.MyEnum.enum3) + test(do[Test.MyEnum.enum1][1] == Test.MyEnum.enum3) + test(len(ro) == 3) + test(len(ro[Test.MyEnum.enum3]) == 3) + test(ro[Test.MyEnum.enum3][0] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum3][1] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum3][2] == Test.MyEnum.enum2) + test(len(ro[Test.MyEnum.enum2]) == 2) + test(ro[Test.MyEnum.enum2][0] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum2][1] == Test.MyEnum.enum2) + test(len(ro[Test.MyEnum.enum1]) == 2) + test(ro[Test.MyEnum.enum1][0] == Test.MyEnum.enum3) + test(ro[Test.MyEnum.enum1][1] == Test.MyEnum.enum3) + + # + # opIntS + # + lengths = ( 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 ) + for l in lengths: + s = [] + for i in range(l): + s.append(i) + r = p.opIntS(s) + test(len(r) == l) + for j in range(len(r)): + test(r[j] == -j) + + + # + # opContext + # + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + r = p.opContext() + test(len(p.ice_getContext()) == 0) + test(r != ctx) + + r = p.opContext(ctx) + test(len(p.ice_getContext()) == 0) + test(r == ctx) + + p2 = Test.MyClassPrx.checkedCast(p.ice_context(ctx)) + test(p2.ice_getContext() == ctx) + r = p2.opContext() + test(r == ctx) + r = p2.opContext(ctx) + test(r == ctx) + + # + # Test implicit context propagation + # + if p.ice_getConnection(): + impls = ( 'Shared', 'PerThread' ) + for i in impls: + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + initData.properties.setProperty('Ice.ImplicitContext', i) + ic = Ice.initialize(data=initData) + + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + p1 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy('test:default -p 12010')) + + ic.getImplicitContext().setContext(ctx) + test(ic.getImplicitContext().getContext() == ctx) + test(p1.opContext() == ctx) + + test(ic.getImplicitContext().containsKey('zero') == False) + r = ic.getImplicitContext().put('zero', 'ZERO') + test(r == '') + test(ic.getImplicitContext().containsKey('zero') == True) + test(ic.getImplicitContext().get('zero') == 'ZERO') + + ctx = ic.getImplicitContext().getContext() + test(p1.opContext() == ctx) + + prxContext = {'one': 'UN', 'four': 'QUATRE'} + + combined = ctx.copy() + combined.update(prxContext) + test(combined['one'] == 'UN') + + p2 = Test.MyClassPrx.uncheckedCast(p1.ice_context(prxContext)) + + ic.getImplicitContext().setContext({}) + test(p2.opContext() == prxContext) + + ic.getImplicitContext().setContext(ctx) + test(p2.opContext() == combined) + + test(ic.getImplicitContext().remove('one') == 'ONE') + + ic.destroy() + + d = 1278312346.0 / 13.0 + ds = [] + for i in range(5): + ds.append(d) + p.opDoubleMarshaling(d, ds) + + # + # opIdempotent + # + p.opIdempotent() + + # + # opNonmutating + # + p.opNonmutating() + + test(p.opByte1(0xFF) == 0xFF) + test(p.opShort1(0x7FFF) == 0x7FFF) + test(p.opInt1(0x7FFFFFFF) == 0x7FFFFFFF) + test(p.opLong1(0x7FFFFFFFFFFFFFFF) == 0x7FFFFFFFFFFFFFFF) + test(p.opFloat1(1.0) == 1.0) + test(p.opDouble1(1.0) == 1.0) + test(p.opString1("opString1") == "opString1") + test(len(p.opStringS1(None)) == 0) + test(len(p.opByteBoolD1(None)) == 0) + test(len(p.opStringS2(None)) == 0) + test(len(p.opByteBoolD2(None)) == 0) + + d = Test.MyDerivedClassPrx.uncheckedCast(p) + s = Test.MyStruct1() + s.tesT = "Test.MyStruct1.s" + s.myClass = None + s.myStruct1 = "Test.MyStruct1.myStruct1" + s = d.opMyStruct1(s) + test(s.tesT == "Test.MyStruct1.s") + test(s.myClass == None) + test(s.myStruct1 == "Test.MyStruct1.myStruct1") + c = Test.MyClass1() + c.tesT = "Test.MyClass1.testT" + c.myClass = None + c.myClass1 = "Test.MyClass1.myClass1" + c = d.opMyClass1(c) + test(c.tesT == "Test.MyClass1.testT") + test(c.myClass == None) + test(c.myClass1 == "Test.MyClass1.myClass1") diff --git a/python/test/Ice/operations/TwowaysAMI.py b/python/test/Ice/operations/TwowaysAMI.py new file mode 100644 index 00000000000..83ef333dea1 --- /dev/null +++ b/python/test/Ice/operations/TwowaysAMI.py @@ -0,0 +1,1216 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, math, sys, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def __init__(self, communicator=None): + CallbackBase.__init__(self) + self._communicator = communicator + + def ping(self): + self.called() + + def isA(self, r): + test(r) + self.called() + + def id(self, id): + test(id == "::Test::MyDerivedClass") + self.called() + + def ids(self, ids): + test(len(ids) == 3) + self.called() + + def opVoid(self): + self.called() + + def opByte(self, r, b): + test(b == 0xf0) + test(r == 0xff) + self.called() + + def opBool(self, r, b): + test(b) + test(not r) + self.called() + + def opShortIntLong(self, r, s, i, l): + test(s == 10) + test(i == 11) + test(l == 12) + test(r == 12) + self.called() + + def opFloatDouble(self, r, f, d): + test(f - 3.14 < 0.001) + test(d == 1.1E10) + test(r == 1.1E10) + self.called() + + def opString(self, r, s): + test(s == "world hello") + test(r == "hello world") + self.called() + + def opMyEnum(self, r, e): + test(e == Test.MyEnum.enum2) + test(r == Test.MyEnum.enum3) + self.called() + + def opMyClass(self, r, c1, c2): + test(c1.ice_getIdentity() == self._communicator.stringToIdentity("test")) + test(c2.ice_getIdentity() == self._communicator.stringToIdentity("noSuchIdentity")) + test(r.ice_getIdentity() == self._communicator.stringToIdentity("test")) + # We can't do the callbacks below in serialize mode + if self._communicator.getProperties().getPropertyAsInt("Ice.Client.ThreadPool.Serialize") == 0: + r.opVoid() + c1.opVoid() + try: + c2.opVoid() + test(False) + except Ice.ObjectNotExistException: + pass + self.called() + + def opStruct(self, rso, so): + test(rso.p == None) + test(rso.e == Test.MyEnum.enum2) + test(rso.s.s == "def") + test(so.e == Test.MyEnum.enum3) + test(so.s.s == "a new string") + # We can't do the callbacks below in serialize mode. + if self._communicator.getProperties().getPropertyAsInt("Ice.ThreadPool.Client.Serialize") == 0: + so.p.opVoid() + self.called() + + def opByteS(self, rso, bso): + test(len(bso) == 4) + test(len(rso) == 8) + if sys.version_info[0] == 2: + test(bso[0] == '\x22') + test(bso[1] == '\x12') + test(bso[2] == '\x11') + test(bso[3] == '\x01') + test(rso[0] == '\x01') + test(rso[1] == '\x11') + test(rso[2] == '\x12') + test(rso[3] == '\x22') + test(rso[4] == '\xf1') + test(rso[5] == '\xf2') + test(rso[6] == '\xf3') + test(rso[7] == '\xf4') + else: + test(bso[0] == 0x22) + test(bso[1] == 0x12) + test(bso[2] == 0x11) + test(bso[3] == 0x01) + test(rso[0] == 0x01) + test(rso[1] == 0x11) + test(rso[2] == 0x12) + test(rso[3] == 0x22) + test(rso[4] == 0xf1) + test(rso[5] == 0xf2) + test(rso[6] == 0xf3) + test(rso[7] == 0xf4) + self.called() + + def opBoolS(self, rso, bso): + test(len(bso) == 4) + test(bso[0]) + test(bso[1]) + test(not bso[2]) + test(not bso[3]) + test(len(rso) == 3) + test(not rso[0]) + test(rso[1]) + test(rso[2]) + self.called() + + def opShortIntLongS(self, rso, sso, iso, lso): + test(len(sso) == 3) + test(sso[0] == 1) + test(sso[1] == 2) + test(sso[2] == 3) + test(len(iso) == 4) + test(iso[0] == 8) + test(iso[1] == 7) + test(iso[2] == 6) + test(iso[3] == 5) + test(len(lso) == 6) + test(lso[0] == 10) + test(lso[1] == 30) + test(lso[2] == 20) + test(lso[3] == 10) + test(lso[4] == 30) + test(lso[5] == 20) + test(len(rso) == 3) + test(rso[0] == 10) + test(rso[1] == 30) + test(rso[2] == 20) + self.called() + + def opFloatDoubleS(self, rso, fso, dso): + test(len(fso) == 2) + test(fso[0] - 3.14 < 0.001) + test(fso[1] - 1.11 < 0.001) + test(len(dso) == 3) + test(dso[0] == 1.3E10) + test(dso[1] == 1.2E10) + test(dso[2] == 1.1E10) + test(len(rso) == 5) + test(rso[0] == 1.1E10) + test(rso[1] == 1.2E10) + test(rso[2] == 1.3E10) + test(rso[3] - 3.14 < 0.001) + test(rso[4] - 1.11 < 0.001) + self.called() + + def opStringS(self, rso, sso): + test(len(sso) == 4) + test(sso[0] == "abc") + test(sso[1] == "de") + test(sso[2] == "fghi") + test(sso[3] == "xyz") + test(len(rso) == 3) + test(rso[0] == "fghi") + test(rso[1] == "de") + test(rso[2] == "abc") + self.called() + + def opByteSS(self, rso, bso): + test(len(bso) == 2) + test(len(bso[0]) == 1) + test(len(bso[1]) == 3) + test(len(rso) == 4) + test(len(rso[0]) == 3) + test(len(rso[1]) == 1) + test(len(rso[2]) == 1) + test(len(rso[3]) == 2) + if sys.version_info[0] == 2: + test(bso[0][0] == '\xff') + test(bso[1][0] == '\x01') + test(bso[1][1] == '\x11') + test(bso[1][2] == '\x12') + test(rso[0][0] == '\x01') + test(rso[0][1] == '\x11') + test(rso[0][2] == '\x12') + test(rso[1][0] == '\xff') + test(rso[2][0] == '\x0e') + test(rso[3][0] == '\xf2') + test(rso[3][1] == '\xf1') + else: + test(bso[0][0] == 0xff) + test(bso[1][0] == 0x01) + test(bso[1][1] == 0x11) + test(bso[1][2] == 0x12) + test(rso[0][0] == 0x01) + test(rso[0][1] == 0x11) + test(rso[0][2] == 0x12) + test(rso[1][0] == 0xff) + test(rso[2][0] == 0x0e) + test(rso[3][0] == 0xf2) + test(rso[3][1] == 0xf1) + self.called() + + def opBoolSS(self, rso, bso): + test(len(bso) == 4); + test(len(bso[0]) == 1); + test(bso[0][0]); + test(len(bso[1]) == 1); + test(not bso[1][0]); + test(len(bso[2]) == 2); + test(bso[2][0]); + test(bso[2][1]); + test(len(bso[3]) == 3); + test(not bso[3][0]); + test(not bso[3][1]); + test(bso[3][2]); + test(len(rso) == 3); + test(len(rso[0]) == 2); + test(rso[0][0]); + test(rso[0][1]); + test(len(rso[1]) == 1); + test(not rso[1][0]); + test(len(rso[2]) == 1); + test(rso[2][0]); + self.called(); + + def opShortIntLongSS(self, rso, sso, iso, lso): + test(len(rso) == 1); + test(len(rso[0]) == 2); + test(rso[0][0] == 496); + test(rso[0][1] == 1729); + test(len(sso) == 3); + test(len(sso[0]) == 3); + test(sso[0][0] == 1); + test(sso[0][1] == 2); + test(sso[0][2] == 5); + test(len(sso[1]) == 1); + test(sso[1][0] == 13); + test(len(sso[2]) == 0); + test(len(iso) == 2); + test(len(iso[0]) == 1); + test(iso[0][0] == 42); + test(len(iso[1]) == 2); + test(iso[1][0] == 24); + test(iso[1][1] == 98); + test(len(lso) == 2); + test(len(lso[0]) == 2); + test(lso[0][0] == 496); + test(lso[0][1] == 1729); + test(len(lso[1]) == 2); + test(lso[1][0] == 496); + test(lso[1][1] == 1729); + self.called(); + + def opFloatDoubleSS(self, rso, fso, dso): + test(len(fso) == 3) + test(len(fso[0]) == 1) + test(fso[0][0] - 3.14 < 0.001) + test(len(fso[1]) == 1) + test(fso[1][0] - 1.11 < 0.001) + test(len(fso[2]) == 0) + test(len(dso) == 1) + test(len(dso[0]) == 3) + test(dso[0][0] == 1.1E10) + test(dso[0][1] == 1.2E10) + test(dso[0][2] == 1.3E10) + test(len(rso) == 2) + test(len(rso[0]) == 3) + test(rso[0][0] == 1.1E10) + test(rso[0][1] == 1.2E10) + test(rso[0][2] == 1.3E10) + test(len(rso[1]) == 3) + test(rso[1][0] == 1.1E10) + test(rso[1][1] == 1.2E10) + test(rso[1][2] == 1.3E10) + self.called() + + def opStringSS(self, rso, sso): + test(len(sso) == 5) + test(len(sso[0]) == 1) + test(sso[0][0] == "abc") + test(len(sso[1]) == 2) + test(sso[1][0] == "de") + test(sso[1][1] == "fghi") + test(len(sso[2]) == 0) + test(len(sso[3]) == 0) + test(len(sso[4]) == 1) + test(sso[4][0] == "xyz") + test(len(rso) == 3) + test(len(rso[0]) == 1) + test(rso[0][0] == "xyz") + test(len(rso[1]) == 0) + test(len(rso[2]) == 0) + self.called() + + def opByteBoolD(self, ro, do): + di1 = {10: True, 100: False} + test(do == di1) + test(len(ro) == 4) + test(ro[10]) + test(not ro[11]) + test(not ro[100]) + test(ro[101]) + self.called() + + def opShortIntD(self, ro, do): + di1 = {110: -1, 1100: 123123} + test(do == di1) + test(len(ro) == 4) + test(ro[110] == -1) + test(ro[111] == -100) + test(ro[1100] == 123123) + test(ro[1101] == 0) + self.called() + + def opLongFloatD(self, ro, do): + di1 = {999999110: -1.1, 999999111: 123123.2} + for k in do: + test(math.fabs(do[k] - di1[k]) < 0.01) + test(len(ro) == 4) + test(ro[999999110] - -1.1 < 0.01) + test(ro[999999120] - -100.4 < 0.01) + test(ro[999999111] - 123123.2 < 0.01) + test(ro[999999130] - 0.5 < 0.01) + self.called() + + def opStringStringD(self, ro, do): + di1 = {'foo': 'abc -1.1', 'bar': 'abc 123123.2'} + test(do == di1) + test(len(ro) == 4) + test(ro["foo"] == "abc -1.1") + test(ro["FOO"] == "abc -100.4") + test(ro["bar"] == "abc 123123.2") + test(ro["BAR"] == "abc 0.5") + self.called() + + def opStringMyEnumD(self, ro, do): + di1 = {'abc': Test.MyEnum.enum1, '': Test.MyEnum.enum2} + test(do == di1) + test(len(ro) == 4) + test(ro["abc"] == Test.MyEnum.enum1) + test(ro["qwerty"] == Test.MyEnum.enum3) + test(ro[""] == Test.MyEnum.enum2) + test(ro["Hello!!"] == Test.MyEnum.enum2) + self.called() + + def opMyEnumStringD(self, ro, do): + di1 = {Test.MyEnum.enum1: 'abc'} + test(do == di1) + test(len(ro) == 3) + test(ro[Test.MyEnum.enum1] == "abc") + test(ro[Test.MyEnum.enum2] == "Hello!!") + test(ro[Test.MyEnum.enum3] == "qwerty") + self.called() + + def opMyStructMyEnumD(self, ro, do): + s11 = Test.MyStruct() + s11.i = 1 + s11.j = 1 + s12 = Test.MyStruct() + s12.i = 1 + s12.j = 2 + s22 = Test.MyStruct() + s22.i = 2 + s22.j = 2 + s23 = Test.MyStruct() + s23.i = 2 + s23.j = 3 + di1 = {s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2} + test(do == di1) + test(len(ro) == 4) + test(ro[s11] == Test.MyEnum.enum1) + test(ro[s12] == Test.MyEnum.enum2) + test(ro[s22] == Test.MyEnum.enum3) + test(ro[s23] == Test.MyEnum.enum2) + self.called() + + def opByteBoolDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][10]) + test(not ro[0][11]) + test(ro[0][101]) + test(len(ro[1]) == 2) + test(ro[1][10]) + test(not ro[1][100]) + test(len(do) == 3) + test(len(do[0]) == 2) + test(not do[0][100]) + test(not do[0][101]) + test(len(do[1]) == 2) + test(do[1][10]) + test(not do[1][100]) + test(len(do[2]) == 3) + test(do[2][10]) + test(not do[2][11]) + test(do[2][101]) + self.called() + + def opShortIntDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][110] == -1) + test(ro[0][111] == -100) + test(ro[0][1101] == 0) + test(len(ro[1]) == 2) + test(ro[1][110] == -1) + test(ro[1][1100] == 123123) + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][100] == -1001) + test(len(do[1]) == 2) + test(do[1][110] == -1) + test(do[1][1100] == 123123) + test(len(do[2]) == 3) + test(do[2][110] == -1) + test(do[2][111] == -100) + test(do[2][1101] == 0) + self.called() + + def opLongFloatDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][999999110] - -1.1 < 0.01) + test(ro[0][999999120] - -100.4 < 0.01) + test(ro[0][999999130] - 0.5 < 0.01) + test(len(ro[1]) == 2) + test(ro[1][999999110] - -1.1 < 0.01) + test(ro[1][999999111] - 123123.2 < 0.01) + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][999999140] - 3.14 < 0.01) + test(len(do[1]) == 2) + test(do[1][999999110] - -1.1 < 0.01) + test(do[1][999999111] - 123123.2 < 0.01) + test(len(do[2]) == 3) + test(do[2][999999110] - -1.1 < 0.01) + test(do[2][999999120] - -100.4 < 0.01) + test(do[2][999999130] - 0.5 < 0.01) + self.called() + + def opStringStringDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0]["foo"] == "abc -1.1") + test(ro[0]["FOO"] == "abc -100.4") + test(ro[0]["BAR"] == "abc 0.5") + test(len(ro[1]) == 2) + test(ro[1]["foo"] == "abc -1.1") + test(ro[1]["bar"] == "abc 123123.2") + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0]["f00"] == "ABC -3.14") + test(len(do[1]) == 2) + test(do[1]["foo"] == "abc -1.1") + test(do[1]["bar"] == "abc 123123.2") + test(len(do[2]) == 3) + test(do[2]["foo"] == "abc -1.1") + test(do[2]["FOO"] == "abc -100.4") + test(do[2]["BAR"] == "abc 0.5") + self.called() + + def opStringMyEnumDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0]["abc"] == Test.MyEnum.enum1) + test(ro[0]["qwerty"] == Test.MyEnum.enum3) + test(ro[0]["Hello!!"] == Test.MyEnum.enum2) + test(len(ro[1]) == 2) + test(ro[1]["abc"] == Test.MyEnum.enum1) + test(ro[1][""] == Test.MyEnum.enum2) + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0]["Goodbye"] == Test.MyEnum.enum1) + test(len(do[1]) == 2) + test(do[1]["abc"] == Test.MyEnum.enum1) + test(do[1][""] == Test.MyEnum.enum2) + test(len(do[2]) == 3) + test(do[2]["abc"] == Test.MyEnum.enum1) + test(do[2]["qwerty"] == Test.MyEnum.enum3) + test(do[2]["Hello!!"] == Test.MyEnum.enum2) + self.called() + + def opMyEnumStringDS(self, ro, do): + test(len(ro) == 2) + test(len(ro[0]) == 2) + test(ro[0][Test.MyEnum.enum2] == "Hello!!") + test(ro[0][Test.MyEnum.enum3] == "qwerty") + test(len(ro[1]) == 1) + test(ro[1][Test.MyEnum.enum1] == "abc") + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][Test.MyEnum.enum1] == "Goodbye") + test(len(do[1]) == 1) + test(do[1][Test.MyEnum.enum1] == "abc") + test(len(do[2]) == 2) + test(do[2][Test.MyEnum.enum2] == "Hello!!") + test(do[2][Test.MyEnum.enum3] == "qwerty") + self.called() + + def opMyStructMyEnumDS(self, ro, do): + s11 = Test.MyStruct(1, 1) + s12 = Test.MyStruct(1, 2) + s22 = Test.MyStruct(2, 2) + s23 = Test.MyStruct(2, 3) + test(len(ro) == 2) + test(len(ro[0]) == 3) + test(ro[0][s11] == Test.MyEnum.enum1) + test(ro[0][s22] == Test.MyEnum.enum3) + test(ro[0][s23] == Test.MyEnum.enum2) + test(len(ro[1]) == 2) + test(ro[1][s11] == Test.MyEnum.enum1) + test(ro[1][s12] == Test.MyEnum.enum2) + test(len(do) == 3) + test(len(do[0]) == 1) + test(do[0][s23] == Test.MyEnum.enum3) + test(len(do[1]) == 2) + test(do[1][s11] == Test.MyEnum.enum1) + test(do[1][s12] == Test.MyEnum.enum2) + test(len(do[2]) == 3) + test(do[2][s11] == Test.MyEnum.enum1) + test(do[2][s22] == Test.MyEnum.enum3) + test(do[2][s23] == Test.MyEnum.enum2) + self.called() + + def opByteByteSD(self, ro, do): + if sys.version_info[0] == 2: + test(len(do) == 1) + test(len(do[0xf1]) == 2) + test(do[0xf1][0] == '\xf2') + test(do[0xf1][1] == '\xf3') + test(len(ro) == 3) + test(len(ro[0x01]) == 2) + test(ro[0x01][0] == '\x01') + test(ro[0x01][1] == '\x11') + test(len(ro[0x22]) == 1) + test(ro[0x22][0] == '\x12') + test(len(ro[0xf1]) == 2) + test(ro[0xf1][0] == '\xf2') + test(ro[0xf1][1] == '\xf3') + else: + test(len(do) == 1) + test(len(do[0xf1]) == 2) + test(do[0xf1][0] == 0xf2) + test(do[0xf1][1] == 0xf3) + test(len(ro) == 3) + test(len(ro[0x01]) == 2) + test(ro[0x01][0] == 0x01) + test(ro[0x01][1] == 0x11) + test(len(ro[0x22]) == 1) + test(ro[0x22][0] == 0x12) + test(len(ro[0xf1]) == 2) + test(ro[0xf1][0] == 0xf2) + test(ro[0xf1][1] == 0xf3) + self.called() + + def opBoolBoolSD(self, ro, do): + test(len(do) == 1) + test(len(do[False]) == 2) + test(do[False][0]) + test(not do[False][1]) + test(len(ro) == 2) + test(len(ro[False]) == 2) + test(ro[False][0]) + test(not ro[False][1]) + test(len(ro[True]) == 3) + test(not ro[True][0]) + test(ro[True][1]) + test(ro[True][2]) + self.called() + + def opShortShortSD(self, ro, do): + test(len(do) == 1) + test(len(do[4]) == 2) + test(do[4][0] == 6) + test(do[4][1] == 7) + test(len(ro) == 3) + test(len(ro[1]) == 3) + test(ro[1][0] == 1) + test(ro[1][1] == 2) + test(ro[1][2] == 3) + test(len(ro[2]) == 2) + test(ro[2][0] == 4) + test(ro[2][1] == 5) + test(len(ro[4]) == 2) + test(ro[4][0] == 6) + test(ro[4][1] == 7) + self.called() + + def opIntIntSD(self, ro, do): + test(len(do) == 1) + test(len(do[400]) == 2) + test(do[400][0] == 600) + test(do[400][1] == 700) + test(len(ro) == 3) + test(len(ro[100]) == 3) + test(ro[100][0] == 100) + test(ro[100][1] == 200) + test(ro[100][2] == 300) + test(len(ro[200]) == 2) + test(ro[200][0] == 400) + test(ro[200][1] == 500) + test(len(ro[400]) == 2) + test(ro[400][0] == 600) + test(ro[400][1] == 700) + self.called() + + def opLongLongSD(self, ro, do): + test(len(do) == 1) + test(len(do[999999992]) == 2) + test(do[999999992][0] == 999999110) + test(do[999999992][1] == 999999120) + test(len(ro) == 3) + test(len(ro[999999990]) == 3) + test(ro[999999990][0] == 999999110) + test(ro[999999990][1] == 999999111) + test(ro[999999990][2] == 999999110) + test(len(ro[999999991]) == 2) + test(ro[999999991][0] == 999999120) + test(ro[999999991][1] == 999999130) + test(len(ro[999999992]) == 2) + test(ro[999999992][0] == 999999110) + test(ro[999999992][1] == 999999120) + self.called() + + def opStringFloatSD(self, ro, do): + test(len(do) == 1) + test(len(do["aBc"]) == 2) + test(do["aBc"][0] - -3.14 < 0.10) + test(do["aBc"][1] - 3.14 < 0.10) + test(len(ro) == 3) + test(len(ro["abc"]) == 3) + test(ro["abc"][0] - -1.1 < 0.10) + test(ro["abc"][1] - 123123.2 < 0.10) + test(ro["abc"][2] - 100.0 < 0.10) + test(len(ro["ABC"]) == 2) + test(ro["ABC"][0] - 42.24 < 0.10) + test(ro["ABC"][1] - -1.61 < 0.10) + test(len(ro["aBc"]) == 2) + test(ro["aBc"][0] - -3.14 < 0.10) + test(ro["aBc"][1] - 3.14 < 0.10) + self.called() + + def opStringDoubleSD(self, ro, do): + test(len(do) == 1) + test(len(do[""]) == 2) + test(do[""][0] == 1.6E10) + test(do[""][1] == 1.7E10) + test(len(ro) == 3) + test(len(ro["Hello!!"]) == 3) + test(ro["Hello!!"][0] == 1.1E10) + test(ro["Hello!!"][1] == 1.2E10) + test(ro["Hello!!"][2] == 1.3E10) + test(len(ro["Goodbye"]) == 2) + test(ro["Goodbye"][0] == 1.4E10) + test(ro["Goodbye"][1] == 1.5E10) + test(len(ro[""]) == 2) + test(ro[""][0] == 1.6E10) + test(ro[""][1] == 1.7E10) + self.called() + + def opStringStringSD(self, ro, do): + test(len(do) == 1) + test(len(do["ghi"]) == 2) + test(do["ghi"][0] == "and") + test(do["ghi"][1] == "xor") + test(len(ro) == 3) + test(len(ro["abc"]) == 3) + test(ro["abc"][0] == "abc") + test(ro["abc"][1] == "de") + test(ro["abc"][2] == "fghi") + test(len(ro["def"]) == 2) + test(ro["def"][0] == "xyz") + test(ro["def"][1] == "or") + test(len(ro["ghi"]) == 2) + test(ro["ghi"][0] == "and") + test(ro["ghi"][1] == "xor") + self.called() + + def opMyEnumMyEnumSD(self, ro, do): + test(len(do) == 1) + test(len(do[Test.MyEnum.enum1]) == 2) + test(do[Test.MyEnum.enum1][0] == Test.MyEnum.enum3) + test(do[Test.MyEnum.enum1][1] == Test.MyEnum.enum3) + test(len(ro) == 3) + test(len(ro[Test.MyEnum.enum3]) == 3) + test(ro[Test.MyEnum.enum3][0] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum3][1] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum3][2] == Test.MyEnum.enum2) + test(len(ro[Test.MyEnum.enum2]) == 2) + test(ro[Test.MyEnum.enum2][0] == Test.MyEnum.enum1) + test(ro[Test.MyEnum.enum2][1] == Test.MyEnum.enum2) + test(len(ro[Test.MyEnum.enum1]) == 2) + test(ro[Test.MyEnum.enum1][0] == Test.MyEnum.enum3) + test(ro[Test.MyEnum.enum1][1] == Test.MyEnum.enum3) + self.called() + + def opIntS(self, r): + for j in range(0, len(r)): + test(r[j] == -j) + self.called() + + def opIdempotent(self): + self.called() + + def opNonmutating(self): + self.called() + + def opDerived(self): + self.called() + + def exCB(self, ex): + test(False) + +def twowaysAMI(communicator, p): + cb = Callback() + p.begin_ice_ping(cb.ping, cb.exCB) + cb.check() + + cb = Callback() + p.begin_ice_isA(Test.MyClass.ice_staticId(), cb.isA, cb.exCB) + cb.check() + + cb = Callback() + p.begin_ice_id(cb.id, cb.exCB) + cb.check() + + cb = Callback() + p.begin_ice_ids(cb.ids, cb.exCB) + cb.check() + + r = p.begin_opVoid() + p.end_opVoid(r) + + cb = Callback() + p.begin_opVoid(cb.opVoid, cb.exCB) + cb.check() + + r = p.begin_opByte(0xff, 0x0f) + (ret, p3) = p.end_opByte(r) + test(p3 == 0xf0) + test(ret == 0xff) + + cb = Callback() + p.begin_opByte(0xff, 0x0f, cb.opByte, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opBool(True, False, cb.opBool, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opShortIntLong(10, 11, 12, cb.opShortIntLong, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opFloatDouble(3.14, 1.1E10, cb.opFloatDouble, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opString("hello", "world", cb.opString, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opMyEnum(Test.MyEnum.enum2, cb.opMyEnum, cb.exCB) + cb.check() + + cb = Callback(communicator) + p.begin_opMyClass(p, cb.opMyClass, cb.exCB) + cb.check() + + si1 = Test.Structure() + si1.p = p + si1.e = Test.MyEnum.enum3 + si1.s = Test.AnotherStruct() + si1.s.s = "abc" + si2 = Test.Structure() + si2.p = None + si2.e = Test.MyEnum.enum2 + si2.s = Test.AnotherStruct() + si2.s.s = "def" + + cb = Callback(communicator) + p.begin_opStruct(si1, si2, cb.opStruct, cb.exCB) + cb.check() + + bsi1 = (0x01, 0x11, 0x12, 0x22) + bsi2 = (0xf1, 0xf2, 0xf3, 0xf4) + + cb = Callback() + p.begin_opByteS(bsi1, bsi2, cb.opByteS, cb.exCB) + cb.check() + + bsi1 = (True, True, False) + bsi2 = (False,) + + cb = Callback() + p.begin_opBoolS(bsi1, bsi2, cb.opBoolS, cb.exCB) + cb.check() + + ssi = (1, 2, 3) + isi = (5, 6, 7, 8) + lsi = (10, 30, 20) + + cb = Callback() + p.begin_opShortIntLongS(ssi, isi, lsi, cb.opShortIntLongS, cb.exCB) + cb.check() + + fsi = (3.14, 1.11) + dsi = (1.1E10, 1.2E10, 1.3E10) + + cb = Callback() + p.begin_opFloatDoubleS(fsi, dsi, cb.opFloatDoubleS, cb.exCB) + cb.check() + + ssi1 = ('abc', 'de', 'fghi') + ssi2 = ('xyz',) + + cb = Callback() + p.begin_opStringS(ssi1, ssi2, cb.opStringS, cb.exCB) + cb.check() + + bsi1 = ((0x01, 0x11, 0x12), (0xff,)) + bsi2 = ((0x0e,), (0xf2, 0xf1)) + + cb = Callback() + p.begin_opByteSS(bsi1, bsi2, cb.opByteSS, cb.exCB) + cb.check() + + bsi1 = ((True,), (False,), (True, True),) + bsi2 = ((False, False, True),) + + cb = Callback() + p.begin_opBoolSS(bsi1, bsi2, cb.opBoolSS, cb.exCB) + cb.check(); + + ssi = ((1,2,5), (13,), ()) + isi = ((24, 98), (42,)) + lsi = ((496, 1729),) + + cb = Callback() + p.begin_opShortIntLongSS(ssi, isi, lsi, cb.opShortIntLongSS, cb.exCB) + cb.check() + + fsi = ((3.14,), (1.11,), ()) + dsi = ((1.1E10, 1.2E10, 1.3E10),) + + cb = Callback() + p.begin_opFloatDoubleSS(fsi, dsi, cb.opFloatDoubleSS, cb.exCB) + cb.check() + + ssi1 = (('abc',), ('de', 'fghi')) + ssi2 = ((), (), ('xyz',)) + + cb = Callback() + p.begin_opStringSS(ssi1, ssi2, cb.opStringSS, cb.exCB) + cb.check() + + di1 = {10: True, 100: False} + di2 = {10: True, 11: False, 101: True} + + cb = Callback() + p.begin_opByteBoolD(di1, di2, cb.opByteBoolD, cb.exCB) + cb.check() + + di1 = {110: -1, 1100: 123123} + di2 = {110: -1, 111: -100, 1101: 0} + + cb = Callback() + p.begin_opShortIntD(di1, di2, cb.opShortIntD, cb.exCB) + cb.check() + + di1 = {999999110: -1.1, 999999111: 123123.2} + di2 = {999999110: -1.1, 999999120: -100.4, 999999130: 0.5} + + cb = Callback() + p.begin_opLongFloatD(di1, di2, cb.opLongFloatD, cb.exCB) + cb.check() + + di1 = {'foo': 'abc -1.1', 'bar': 'abc 123123.2'} + di2 = {'foo': 'abc -1.1', 'FOO': 'abc -100.4', 'BAR': 'abc 0.5'} + + cb = Callback() + p.begin_opStringStringD(di1, di2, cb.opStringStringD, cb.exCB) + cb.check() + + di1 = {'abc': Test.MyEnum.enum1, '': Test.MyEnum.enum2} + di2 = {'abc': Test.MyEnum.enum1, 'qwerty': Test.MyEnum.enum3, 'Hello!!': Test.MyEnum.enum2} + + cb = Callback() + p.begin_opStringMyEnumD(di1, di2, cb.opStringMyEnumD, cb.exCB) + cb.check() + + di1 = {Test.MyEnum.enum1: 'abc'} + di2 = {Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'} + + cb = Callback() + p.begin_opMyEnumStringD(di1, di2, cb.opMyEnumStringD, cb.exCB) + cb.check() + + s11 = Test.MyStruct() + s11.i = 1 + s11.j = 1 + s12 = Test.MyStruct() + s12.i = 1 + s12.j = 2 + s22 = Test.MyStruct() + s22.i = 2 + s22.j = 2 + s23 = Test.MyStruct() + s23.i = 2 + s23.j = 3 + di1 = {s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2} + di2 = {s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2} + + cb = Callback() + p.begin_opMyStructMyEnumD(di1, di2, cb.opMyStructMyEnumD, cb.exCB) + cb.check() + + dsi1 = ({ 10: True, 100: False }, { 10: True, 11: False, 101: True }) + dsi2 = ({ 100: False, 101: False },) + + cb = Callback() + p.begin_opByteBoolDS(dsi1, dsi2, cb.opByteBoolDS, cb.exCB) + cb.check() + + dsi1 = ({ 110: -1, 1100: 123123 }, { 110: -1, 111: -100, 1101: 0 }) + dsi2 = ({ 100: -1001 },) + + cb = Callback() + p.begin_opShortIntDS(dsi1, dsi2, cb.opShortIntDS, cb.exCB) + cb.called() + + dsi1 = ({ 999999110: -1.1, 999999111: 123123.2 }, { 999999110: -1.1, 999999120: -100.4, 999999130: 0.5 }) + dsi2 = ({ 999999140: 3.14 },) + + cb = Callback() + p.begin_opLongFloatDS(dsi1, dsi2, cb.opLongFloatDS, cb.exCB) + cb.called() + + dsi1 = ({ "foo": "abc -1.1", "bar": "abc 123123.2" }, { "foo": "abc -1.1", "FOO": "abc -100.4", "BAR": "abc 0.5" }) + dsi2 = ({ "f00": "ABC -3.14" },) + + cb = Callback() + p.begin_opStringStringDS(dsi1, dsi2, cb.opStringStringDS, cb.exCB) + cb.called() + + dsi1 = ( + { "abc": Test.MyEnum.enum1, "": Test.MyEnum.enum2 }, + { "abc": Test.MyEnum.enum1, "qwerty": Test.MyEnum.enum3, "Hello!!": Test.MyEnum.enum2 } + ) + + dsi2 = ({ "Goodbye": Test.MyEnum.enum1 },) + + cb = Callback() + p.begin_opStringMyEnumDS(dsi1, dsi2, cb.opStringMyEnumDS, cb.exCB) + cb.called() + + dsi1 = ({ Test.MyEnum.enum1: 'abc' }, { Test.MyEnum.enum2: 'Hello!!', Test.MyEnum.enum3: 'qwerty'}) + dsi2 = ({ Test.MyEnum.enum1: 'Goodbye' },) + + cb = Callback() + p.begin_opMyEnumStringDS(dsi1, dsi2, cb.opMyEnumStringDS, cb.exCB) + cb.called() + + s11 = Test.MyStruct(1, 1) + s12 = Test.MyStruct(1, 2) + + s22 = Test.MyStruct(2, 2) + s23 = Test.MyStruct(2, 3) + + dsi1 = ( + { s11: Test.MyEnum.enum1, s12: Test.MyEnum.enum2 }, + { s11: Test.MyEnum.enum1, s22: Test.MyEnum.enum3, s23: Test.MyEnum.enum2 } + ) + dsi2 = ({ s23: Test.MyEnum.enum3 },) + + cb = Callback() + p.begin_opMyStructMyEnumDS(dsi1, dsi2, cb.opMyStructMyEnumDS, cb.exCB) + cb.called() + + sdi1 = { 0x01: (0x01, 0x11), 0x22: (0x12,) } + sdi2 = { 0xf1: (0xf2, 0xf3) } + + cb = Callback() + p.begin_opByteByteSD(sdi1, sdi2, cb.opByteByteSD, cb.exCB) + cb.called() + + sdi1 = { False: (True, False), True: (False, True, True) } + sdi2 = { False: (True, False) } + + cb = Callback() + p.begin_opBoolBoolSD(sdi1, sdi2, cb.opBoolBoolSD, cb.exCB) + cb.called() + + sdi1 = { 1: (1, 2, 3), 2: (4, 5) } + sdi2 = { 4: (6, 7) } + + cb = Callback() + p.begin_opShortShortSD(sdi1, sdi2, cb.opShortShortSD, cb.exCB) + cb.called() + + sdi1 = { 100: (100, 200, 300), 200: (400, 500) } + sdi2 = { 400: (600, 700) } + + cb = Callback() + p.begin_opIntIntSD(sdi1, sdi2, cb.opIntIntSD, cb.exCB) + cb.called() + + sdi1 = { 999999990: (999999110, 999999111, 999999110), 999999991: (999999120, 999999130) } + sdi2 = { 999999992: (999999110, 999999120) } + + cb = Callback() + p.begin_opLongLongSD(sdi1, sdi2, cb.opLongLongSD, cb.exCB) + cb.called() + + sdi1 = { "abc": (-1.1, 123123.2, 100.0), "ABC": (42.24, -1.61) } + sdi2 = { "aBc": (-3.14, 3.14) } + + cb = Callback() + p.begin_opStringFloatSD(sdi1, sdi2, cb.opStringFloatSD, cb.exCB) + cb.called() + + sdi1 = { "Hello!!": (1.1E10, 1.2E10, 1.3E10), "Goodbye": (1.4E10, 1.5E10) } + sdi2 = { "": (1.6E10, 1.7E10) } + + cb = Callback() + p.begin_opStringDoubleSD(sdi1, sdi2, cb.opStringDoubleSD, cb.exCB); + cb.called() + + sdi1 = { "abc": ("abc", "de", "fghi") , "def": ("xyz", "or") } + sdi2 = { "ghi": ("and", "xor") } + + cb = Callback() + p.begin_opStringStringSD(sdi1, sdi2, cb.opStringStringSD, cb.exCB) + cb.called() + + sdi1 = { + Test.MyEnum.enum3: (Test.MyEnum.enum1, Test.MyEnum.enum1, Test.MyEnum.enum2), + Test.MyEnum.enum2: (Test.MyEnum.enum1, Test.MyEnum.enum2) + } + sdi2 = { Test.MyEnum.enum1: (Test.MyEnum.enum3, Test.MyEnum.enum3) } + + cb = Callback() + p.begin_opMyEnumMyEnumSD(sdi1, sdi2, cb.opMyEnumMyEnumSD, cb.exCB) + cb.called() + + lengths = ( 0, 1, 2, 126, 127, 128, 129, 253, 254, 255, 256, 257, 1000 ) + for l in lengths: + s = [] + for i in range(l): + s.append(i) + cb = Callback(l) + p.begin_opIntS(s, cb.opIntS, cb.exCB) + cb.check() + + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + test(len(p.ice_getContext()) == 0) + r = p.begin_opContext() + c = p.end_opContext(r) + test(c != ctx) + + test(len(p.ice_getContext()) == 0) + r = p.begin_opContext(_ctx=ctx) + c = p.end_opContext(r) + test(c == ctx) + + p2 = Test.MyClassPrx.checkedCast(p.ice_context(ctx)) + test(p2.ice_getContext() == ctx) + r = p2.begin_opContext() + c = p2.end_opContext(r) + test(c == ctx) + + r = p2.begin_opContext(_ctx=ctx) + c = p2.end_opContext(r) + test(c == ctx) + + # + # Test implicit context propagation + # + if p.ice_getConnection(): + impls = ( 'Shared', 'PerThread' ) + for i in impls: + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + initData.properties.setProperty('Ice.ImplicitContext', i) + ic = Ice.initialize(data=initData) + + ctx = {'one': 'ONE', 'two': 'TWO', 'three': 'THREE'} + + p3 = Test.MyClassPrx.uncheckedCast(ic.stringToProxy("test:default -p 12010")) + + ic.getImplicitContext().setContext(ctx) + test(ic.getImplicitContext().getContext() == ctx) + r = p3.begin_opContext() + c = p3.end_opContext(r) + test(c == ctx) + + ic.getImplicitContext().put('zero', 'ZERO') + + ctx = ic.getImplicitContext().getContext() + r = p3.begin_opContext() + c = p3.end_opContext(r) + test(c == ctx) + + prxContext = {'one': 'UN', 'four': 'QUATRE'} + + combined = {} + combined.update(ctx) + combined.update(prxContext) + test(combined['one'] == 'UN') + + p3 = Test.MyClassPrx.uncheckedCast(p3.ice_context(prxContext)) + ic.getImplicitContext().setContext({}) + r = p3.begin_opContext() + c = p3.end_opContext(r) + test(c == prxContext) + + ic.getImplicitContext().setContext(ctx) + r = p3.begin_opContext() + c = p3.end_opContext(r) + test(c == combined) + + ic.destroy() + + cb = Callback() + p.begin_opIdempotent(cb.opIdempotent, cb.exCB) + cb.check() + + cb = Callback() + p.begin_opNonmutating(cb.opNonmutating, cb.exCB) + cb.check() + + derived = Test.MyDerivedClassPrx.checkedCast(p) + test(derived) + cb = Callback() + derived.begin_opDerived(cb.opDerived, cb.exCB) + cb.check() + + + r = p.begin_opByte1(0xFF) + test(p.end_opByte1(r) == 0xFF) + + r = p.begin_opShort1(0x7FFF) + test(p.end_opShort1(r) == 0x7FFF) + + r = p.begin_opInt1(0x7FFFFFFF) + test(p.end_opInt1(r) == 0x7FFFFFFF) + + r = p.begin_opLong1(0x7FFFFFFFFFFFFFFF) + test(p.end_opLong1(r) == 0x7FFFFFFFFFFFFFFF) + + r = p.begin_opFloat1(1.0) + test(p.end_opFloat1(r) == 1.0) + + r = p.begin_opDouble1(1.0) + test(p.end_opDouble1(r) == 1.0) + + r = p.begin_opString1("opString1") + test(p.end_opString1(r) == "opString1") + + r = p.begin_opStringS1(None) + test(len(p.end_opStringS1(r)) == 0) + + r = p.begin_opByteBoolD1(None) + test(len(p.end_opByteBoolD1(r)) == 0) + + r = p.begin_opStringS2(None) + test(len(p.end_opStringS2(r)) == 0) + + r = p.begin_opByteBoolD2(None) + test(len(p.end_opByteBoolD2(r)) == 0) diff --git a/python/test/Ice/operations/run.py b/python/test/Ice/operations/run.py new file mode 100755 index 00000000000..767b20c0a2c --- /dev/null +++ b/python/test/Ice/operations/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("tests with regular server.") +TestUtil.clientServerTest() +print("tests with AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") +print("tests with collocated server.") +TestUtil.collocatedTest(" --Ice.ThreadPool.Client.SizeMax=2 --Ice.ThreadPool.Client.SizeWarn=0") diff --git a/python/test/Ice/optional/AllTests.py b/python/test/Ice/optional/AllTests.py new file mode 100644 index 00000000000..051e415e9f4 --- /dev/null +++ b/python/test/Ice/optional/AllTests.py @@ -0,0 +1,774 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + ref = "initial:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + initial = Test.InitialPrx.checkedCast(base) + test(initial) + test(initial == base) + print("ok") + + sys.stdout.write("testing optional data members... ") + sys.stdout.flush() + + oo1 = Test.OneOptional() + test(oo1.a is Ice.Unset) + oo1.a = 15 + + oo2 = Test.OneOptional(16) + test(oo2.a == 16) + + mo1 = Test.MultiOptional() + test(mo1.a is Ice.Unset) + test(mo1.b is Ice.Unset) + test(mo1.c is Ice.Unset) + test(mo1.d is Ice.Unset) + test(mo1.e is Ice.Unset) + test(mo1.f is Ice.Unset) + test(mo1.g is Ice.Unset) + test(mo1.h is Ice.Unset) + test(mo1.i is Ice.Unset) + test(mo1.j is Ice.Unset) + test(mo1.k is Ice.Unset) + test(mo1.bs is Ice.Unset) + test(mo1.ss is Ice.Unset) + test(mo1.iid is Ice.Unset) + test(mo1.sid is Ice.Unset) + test(mo1.fs is Ice.Unset) + test(mo1.vs is Ice.Unset) + + test(mo1.shs is Ice.Unset) + test(mo1.es is Ice.Unset) + test(mo1.fss is Ice.Unset) + test(mo1.vss is Ice.Unset) + test(mo1.oos is Ice.Unset) + test(mo1.oops is Ice.Unset) + + test(mo1.ied is Ice.Unset) + test(mo1.ifsd is Ice.Unset) + test(mo1.ivsd is Ice.Unset) + test(mo1.iood is Ice.Unset) + test(mo1.ioopd is Ice.Unset) + + test(mo1.bos is Ice.Unset) + + fs = Test.FixedStruct(78) + vs = Test.VarStruct("hello") + mo1 = Test.MultiOptional(15, True, 19, 78, 99, 5.5, 1.0, "test", Test.MyEnum.MyEnumMember, \ + Test.MultiOptionalPrx.uncheckedCast(communicator.stringToProxy("test")), \ + None, [5], ["test", "test2"], {4:3}, {"test":10}, fs, vs, [1], \ + [Test.MyEnum.MyEnumMember, Test.MyEnum.MyEnumMember], \ + [ fs ], [ vs ], [ oo1 ], \ + [ Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test")) ], \ + {4:Test.MyEnum.MyEnumMember}, {4:fs}, {5:vs}, {5:Test.OneOptional(15)}, \ + {5:Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))}, \ + [False, True, False]) + + test(mo1.a == 15) + test(mo1.b == True) + test(mo1.c == 19) + test(mo1.d == 78) + test(mo1.e == 99) + test(mo1.f == 5.5) + test(mo1.g == 1.0) + test(mo1.h == "test") + test(mo1.i == Test.MyEnum.MyEnumMember) + test(mo1.j == Test.MultiOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + test(mo1.k == None) + test(mo1.bs == [5]) + test(mo1.ss == ["test", "test2"]) + test(mo1.iid[4] == 3) + test(mo1.sid["test"] == 10) + test(mo1.fs == Test.FixedStruct(78)) + test(mo1.vs == Test.VarStruct("hello")) + + test(mo1.shs[0] == 1) + test(mo1.es[0] == Test.MyEnum.MyEnumMember and mo1.es[1] == Test.MyEnum.MyEnumMember) + test(mo1.fss[0] == Test.FixedStruct(78)) + test(mo1.vss[0] == Test.VarStruct("hello")) + test(mo1.oos[0] == oo1) + test(mo1.oops[0] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo1.ied[4] == Test.MyEnum.MyEnumMember) + test(mo1.ifsd[4] == Test.FixedStruct(78)) + test(mo1.ivsd[5] == Test.VarStruct("hello")) + test(mo1.iood[5].a == 15) + test(mo1.ioopd[5] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo1.bos == [False, True, False]) + + print("ok") + + sys.stdout.write("testing marshaling... ") + sys.stdout.flush() + + oo4 = initial.pingPong(Test.OneOptional()) + test(oo4.a is Ice.Unset) + + oo5 = initial.pingPong(oo1) + test(oo1.a == oo5.a) + + mo4 = initial.pingPong(Test.MultiOptional()) + test(mo4.a is Ice.Unset) + test(mo4.b is Ice.Unset) + test(mo4.c is Ice.Unset) + test(mo4.d is Ice.Unset) + test(mo4.e is Ice.Unset) + test(mo4.f is Ice.Unset) + test(mo4.g is Ice.Unset) + test(mo4.h is Ice.Unset) + test(mo4.i is Ice.Unset) + test(mo4.j is Ice.Unset) + test(mo4.k is Ice.Unset) + test(mo4.bs is Ice.Unset) + test(mo4.ss is Ice.Unset) + test(mo4.iid is Ice.Unset) + test(mo4.sid is Ice.Unset) + test(mo4.fs is Ice.Unset) + test(mo4.vs is Ice.Unset) + + test(mo4.shs is Ice.Unset) + test(mo4.es is Ice.Unset) + test(mo4.fss is Ice.Unset) + test(mo4.vss is Ice.Unset) + test(mo4.oos is Ice.Unset) + test(mo4.oops is Ice.Unset) + + test(mo4.ied is Ice.Unset) + test(mo4.ifsd is Ice.Unset) + test(mo4.ivsd is Ice.Unset) + test(mo4.iood is Ice.Unset) + test(mo4.ioopd is Ice.Unset) + + test(mo4.bos is Ice.Unset) + + mo5 = initial.pingPong(mo1) + test(mo5.a == mo1.a) + test(mo5.b == mo1.b) + test(mo5.c == mo1.c) + test(mo5.d == mo1.d) + test(mo5.e == mo1.e) + test(mo5.f == mo1.f) + test(mo5.g == mo1.g) + test(mo5.h == mo1.h) + test(mo5.i == mo1.i) + test(mo5.j == mo1.j) + test(mo5.k == None) + if sys.version_info[0] == 2: + test(mo5.bs == "\x05") + else: + test(mo5.bs[0] == 5) + test(mo5.ss == mo1.ss) + test(mo5.iid[4] == 3) + test(mo5.sid["test"] == 10) + test(mo5.fs == mo1.fs) + test(mo5.vs == mo1.vs) + test(mo5.shs == mo1.shs) + test(mo5.es[0] == Test.MyEnum.MyEnumMember and mo1.es[1] == Test.MyEnum.MyEnumMember) + test(mo5.fss[0] == Test.FixedStruct(78)) + test(mo5.vss[0] == Test.VarStruct("hello")) + test(mo5.oos[0].a == 15) + test(mo5.oops[0] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo5.ied[4] == Test.MyEnum.MyEnumMember) + test(mo5.ifsd[4] == Test.FixedStruct(78)) + test(mo5.ivsd[5] == Test.VarStruct("hello")) + test(mo5.iood[5].a == 15) + test(mo5.ioopd[5] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo5.bos == mo1.bos) + + # Clear the first half of the optional members + mo6 = Test.MultiOptional() + mo6.b = mo5.b + mo6.d = mo5.d + mo6.f = mo5.f + mo6.h = mo5.h + mo6.j = mo5.j + mo6.bs = mo5.bs + mo6.iid = mo5.iid + mo6.fs = mo5.fs + mo6.shs = mo5.shs + mo6.fss = mo5.fss + mo6.oos = mo5.oos + mo6.ifsd = mo5.ifsd + mo6.iood = mo5.iood + mo6.bos = mo5.bos + + mo7 = initial.pingPong(mo6) + test(mo7.a is Ice.Unset) + test(mo7.b == mo1.b) + test(mo7.c is Ice.Unset) + test(mo7.d == mo1.d) + test(mo7.e is Ice.Unset) + test(mo7.f == mo1.f) + test(mo7.g is Ice.Unset) + test(mo7.h == mo1.h) + test(mo7.i is Ice.Unset) + test(mo7.j == mo1.j) + test(mo7.k is Ice.Unset) + if sys.version_info[0] == 2: + test(mo7.bs == "\x05") + else: + test(mo7.bs[0] == 5) + test(mo7.ss is Ice.Unset) + test(mo7.iid[4] == 3) + test(mo7.sid is Ice.Unset) + test(mo7.fs == mo1.fs) + test(mo7.vs is Ice.Unset) + + test(mo7.shs == mo1.shs) + test(mo7.es is Ice.Unset) + test(mo7.fss[0] == Test.FixedStruct(78)) + test(mo7.vss is Ice.Unset) + test(mo7.oos[0].a == 15) + test(mo7.oops is Ice.Unset) + + test(mo7.ied is Ice.Unset) + test(mo7.ifsd[4] == Test.FixedStruct(78)) + test(mo7.ivsd is Ice.Unset) + test(mo7.iood[5].a == 15) + test(mo7.ioopd is Ice.Unset) + + test(mo7.bos == [False, True, False]) + + # Clear the second half of the optional members + mo8 = Test.MultiOptional() + mo8.a = mo5.a + mo8.c = mo5.c + mo8.e = mo5.e + mo8.g = mo5.g + mo8.i = mo5.i + mo8.k = mo8 + mo8.ss = mo5.ss + mo8.sid = mo5.sid + mo8.vs = mo5.vs + + mo8.es = mo5.es + mo8.vss = mo5.vss + mo8.oops = mo5.oops + + mo8.ied = mo5.ied + mo8.ivsd = mo5.ivsd + mo8.ioopd = mo5.ioopd + + mo9 = initial.pingPong(mo8) + test(mo9.a == mo1.a) + test(mo9.b is Ice.Unset) + test(mo9.c == mo1.c) + test(mo9.d is Ice.Unset) + test(mo9.e == mo1.e) + test(mo9.f is Ice.Unset) + test(mo9.g == mo1.g) + test(mo9.h is Ice.Unset) + test(mo9.i == mo1.i) + test(mo9.j is Ice.Unset) + test(mo9.k == mo9) + test(mo9.bs is Ice.Unset) + test(mo9.ss == mo1.ss) + test(mo9.iid is Ice.Unset) + test(mo9.sid["test"] == 10) + test(mo9.fs is Ice.Unset) + test(mo9.vs == mo1.vs) + + test(mo9.shs is Ice.Unset) + test(mo9.es[0] == Test.MyEnum.MyEnumMember and mo1.es[1] == Test.MyEnum.MyEnumMember) + test(mo9.fss is Ice.Unset) + test(mo9.vss[0] == Test.VarStruct("hello")) + test(mo9.oos is Ice.Unset) + test(mo9.oops[0] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo9.ied[4] == Test.MyEnum.MyEnumMember) + test(mo9.ifsd is Ice.Unset) + test(mo9.ivsd[5] == Test.VarStruct("hello")) + test(mo9.iood is Ice.Unset) + test(mo9.ioopd[5] == Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test"))) + + test(mo9.bos is Ice.Unset) + + # + # Use the 1.0 encoding with operations whose only class parameters are optional. + # + initial.sendOptionalClass(True, Test.OneOptional(53)) + initial.ice_encodingVersion(Ice.Encoding_1_0).sendOptionalClass(True, Test.OneOptional(53)) + + r = initial.returnOptionalClass(True) + test(r != Ice.Unset) + r = initial.ice_encodingVersion(Ice.Encoding_1_0).returnOptionalClass(True) + test(r is Ice.Unset) + + recursive1 = [ Test.Recursive() ] + recursive2 = [ Test.Recursive() ] + recursive1[0].value = recursive2; + + outer = Test.Recursive() + outer.value = recursive1 + initial.pingPong(outer) + + print("ok") + + sys.stdout.write("testing marshaling of large containers with fixed size elements... ") + sys.stdout.flush() + + mc = Test.MultiOptional() + + mc.bs = [] + for i in range(1000): + mc.bs.append(0) + mc.shs = [] + for i in range(300): + mc.shs.append(0) + + mc.fss = [] + for i in range(300): + mc.fss.append(Test.FixedStruct()) + + mc.ifsd = {} + for i in range(300): + mc.ifsd[i] = Test.FixedStruct() + + mc = initial.pingPong(mc) + test(len(mc.bs) == 1000) + test(len(mc.shs) == 300) + test(len(mc.fss) == 300) + test(len(mc.ifsd) == 300) + + print("ok") + + sys.stdout.write("testing tag marshaling... ") + sys.stdout.flush() + + b = Test.B() + b2 = initial.pingPong(b) + test(b2.ma is Ice.Unset) + test(b2.mb is Ice.Unset) + test(b2.mc is Ice.Unset) + + b.ma = 10 + b.mb = 11 + b.mc = 12 + b.md = 13 + + b2 = initial.pingPong(b) + test(b2.ma == 10) + test(b2.mb == 11) + test(b2.mc == 12) + test(b2.md == 13) + + print("ok") + + sys.stdout.write("testing marshalling of objects with optional objects...") + sys.stdout.flush() + + f = Test.F() + + f.af = Test.A() + f.ae = f.af + + rf = initial.pingPong(f) + test(rf.ae == rf.af) + + print("ok") + + sys.stdout.write("testing optional with default values... ") + sys.stdout.flush() + + wd = initial.pingPong(Test.WD()) + test(wd.a == 5) + test(wd.s == "test") + wd.a = Ice.Unset + wd.s = Ice.Unset + wd = initial.pingPong(wd) + test(wd.a is Ice.Unset) + test(wd.s is Ice.Unset) + + print("ok") + + if communicator.getProperties().getPropertyAsInt("Ice.Default.SlicedFormat") > 0: + sys.stdout.write("testing marshaling with unknown class slices... ") + sys.stdout.flush() + + c = Test.C() + c.ss = "test" + c.ms = "testms" + c = initial.pingPong(c) + test(c.ma is Ice.Unset) + test(c.mb is Ice.Unset) + test(c.mc is Ice.Unset) + test(c.md is Ice.Unset) + test(c.ss == "test") + test(c.ms == "testms") + + print("ok") + + sys.stdout.write("testing optionals with unknown classes... ") + sys.stdout.flush() + + initial2 = Test.Initial2Prx.uncheckedCast(base) + d = Test.D() + d.ds = "test" + d.seq = ["test1", "test2", "test3", "test4"] + d.ao = Test.A(18) + d.requiredB = 14; + d.requiredA = 14; + initial2.opClassAndUnknownOptional(Test.A(), d) + + print("ok") + + sys.stdout.write("testing optional parameters... ") + sys.stdout.flush() + + (p2, p3) = initial.opByte(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opByte(56) + test(p2 == 56 and p3 == 56) + r = initial.begin_opByte(56) + (p2, p3) = initial.end_opByte(r) + test(p2 == 56 and p3 == 56) + + (p2, p3) = initial.opBool(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opBool(True) + test(p2 == True and p3 == True) + r = initial.begin_opBool(True) + (p2, p3) = initial.end_opBool(r) + test(p2 == True and p3 == True) + + (p2, p3) = initial.opShort(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opShort(56) + test(p2 == 56 and p3 == 56) + r = initial.begin_opShort(56) + (p2, p3) = initial.end_opShort(r) + test(p2 == 56 and p3 == 56) + + (p2, p3) = initial.opInt(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opInt(56) + test(p2 == 56 and p3 == 56) + r = initial.begin_opInt(56) + (p2, p3) = initial.end_opInt(r) + test(p2 == 56 and p3 == 56) + + (p2, p3) = initial.opLong(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opLong(56) + test(p2 == 56 and p3 == 56) + r = initial.begin_opLong(56) + (p2, p3) = initial.end_opLong(r) + test(p2 == 56 and p3 == 56) + + (p2, p3) = initial.opFloat(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opFloat(1.0) + test(p2 == 1.0 and p3 == 1.0) + r = initial.begin_opFloat(1.0) + (p2, p3) = initial.end_opFloat(r) + test(p2 == 1.0 and p3 == 1.0) + + (p2, p3) = initial.opDouble(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opDouble(1.0) + test(p2 == 1.0 and p3 == 1.0) + r = initial.begin_opDouble(1.0) + (p2, p3) = initial.end_opDouble(r) + test(p2 == 1.0 and p3 == 1.0) + + (p2, p3) = initial.opString(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opString("test") + test(p2 == "test" and p3 == "test") + r = initial.begin_opString("test") + (p2, p3) = initial.end_opString(r) + test(p2 == "test" and p3 == "test") + + (p2, p3) = initial.opMyEnum(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + (p2, p3) = initial.opMyEnum(Test.MyEnum.MyEnumMember) + test(p2 == Test.MyEnum.MyEnumMember and p3 == Test.MyEnum.MyEnumMember) + r = initial.begin_opMyEnum(Test.MyEnum.MyEnumMember) + (p2, p3) = initial.end_opMyEnum(r) + test(p2 == Test.MyEnum.MyEnumMember and p3 == Test.MyEnum.MyEnumMember) + + (p2, p3) = initial.opSmallStruct(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = Test.SmallStruct(56) + (p2, p3) = initial.opSmallStruct(p1) + test(p2 == p1 and p3 == p1) + (p2, p3) = initial.opSmallStruct(None) # Test null struct + test(p2.m == 0 and p3.m == 0) + r = initial.begin_opSmallStruct(p1) + (p2, p3) = initial.end_opSmallStruct(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opFixedStruct(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = Test.FixedStruct(56) + (p2, p3) = initial.opFixedStruct(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opFixedStruct(p1) + (p2, p3) = initial.end_opFixedStruct(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opVarStruct(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = Test.VarStruct("test") + (p2, p3) = initial.opVarStruct(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opVarStruct(p1) + (p2, p3) = initial.end_opVarStruct(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opOneOptional(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = Test.OneOptional(58) + (p2, p3) = initial.opOneOptional(p1) + test(p2.a == p1.a and p3.a == p1.a) + r = initial.begin_opOneOptional(p1) + (p2, p3) = initial.end_opOneOptional(r) + test(p2.a == p1.a and p3.a == p1.a) + + (p2, p3) = initial.opOneOptionalProxy(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = Test.OneOptionalPrx.uncheckedCast(communicator.stringToProxy("test")) + (p2, p3) = initial.opOneOptionalProxy(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opOneOptionalProxy(p1) + (p2, p3) = initial.end_opOneOptionalProxy(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opByteSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [56 for x in range(100)] + (p2, p3) = initial.opByteSeq(p1) + test(len(p2) == len(p1) and len(p3) == len(p1)) + if sys.version_info[0] == 2: + test(p2[0] == '\x38') + test(p3[0] == '\x38') + else: + test(p2[0] == 0x38) + test(p3[0] == 0x38) + r = initial.begin_opByteSeq(p1) + (p2, p3) = initial.end_opByteSeq(r) + test(len(p2) == len(p1) and len(p3) == len(p1)) + if sys.version_info[0] == 2: + test(p2[0] == '\x38') + test(p3[0] == '\x38') + else: + test(p2[0] == 0x38) + test(p3[0] == 0x38) + + (p2, p3) = initial.opBoolSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [True for x in range(100)] + (p2, p3) = initial.opBoolSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opBoolSeq(p1) + (p2, p3) = initial.end_opBoolSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opShortSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [56 for x in range(100)] + (p2, p3) = initial.opShortSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opShortSeq(p1) + (p2, p3) = initial.end_opShortSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opIntSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [56 for x in range(100)] + (p2, p3) = initial.opIntSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opIntSeq(p1) + (p2, p3) = initial.end_opIntSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opLongSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [56 for x in range(100)] + (p2, p3) = initial.opLongSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opLongSeq(p1) + (p2, p3) = initial.end_opLongSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opFloatSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [1.0 for x in range(100)] + (p2, p3) = initial.opFloatSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opFloatSeq(p1) + (p2, p3) = initial.end_opFloatSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opDoubleSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [1.0 for x in range(100)] + (p2, p3) = initial.opDoubleSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opDoubleSeq(p1) + (p2, p3) = initial.end_opDoubleSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opStringSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = ["test1" for x in range(100)] + (p2, p3) = initial.opStringSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opStringSeq(p1) + (p2, p3) = initial.end_opStringSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opSmallStructSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [Test.SmallStruct(1) for x in range(10)] + (p2, p3) = initial.opSmallStructSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opSmallStructSeq(p1) + (p2, p3) = initial.end_opSmallStructSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opSmallStructList(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = tuple([Test.SmallStruct(1) for x in range(10)]) + (p2, p3) = initial.opSmallStructList(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opSmallStructList(p1) + (p2, p3) = initial.end_opSmallStructList(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opFixedStructSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [Test.FixedStruct(1) for x in range(10)] + (p2, p3) = initial.opFixedStructSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opFixedStructSeq(p1) + (p2, p3) = initial.end_opFixedStructSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opFixedStructList(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = tuple([Test.FixedStruct(1) for x in range(10)]) + (p2, p3) = initial.opFixedStructList(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opFixedStructList(p1) + (p2, p3) = initial.end_opFixedStructList(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opVarStructSeq(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = [Test.VarStruct("test") for x in range(10)] + (p2, p3) = initial.opVarStructSeq(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opVarStructSeq(p1) + (p2, p3) = initial.end_opVarStructSeq(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opIntIntDict(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = {1:2, 2:3} + (p2, p3) = initial.opIntIntDict(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opIntIntDict(p1) + (p2, p3) = initial.end_opIntIntDict(r) + test(p2 == p1 and p3 == p1) + + (p2, p3) = initial.opStringIntDict(Ice.Unset) + test(p2 is Ice.Unset and p3 is Ice.Unset) + p1 = {"1":2, "2":3} + (p2, p3) = initial.opStringIntDict(p1) + test(p2 == p1 and p3 == p1) + r = initial.begin_opStringIntDict(p1) + (p2, p3) = initial.end_opStringIntDict(r) + test(p2 == p1 and p3 == p1) + + print("ok") + + sys.stdout.write("testing exception optionals... ") + sys.stdout.flush() + + try: + initial.opOptionalException(Ice.Unset, Ice.Unset, Ice.Unset) + except Test.OptionalException as ex: + test(ex.a is Ice.Unset) + test(ex.b is Ice.Unset) + test(ex.o is Ice.Unset) + + try: + initial.opOptionalException(30, "test", Test.OneOptional(53)) + except Test.OptionalException as ex: + test(ex.a == 30) + test(ex.b == "test") + test(ex.o.a == 53) + + try: + # + # Use the 1.0 encoding with an exception whose only class members are optional. + # + initial.ice_encodingVersion(Ice.Encoding_1_0).opOptionalException(30, "test", Test.OneOptional(53)) + except Test.OptionalException as ex: + test(ex.a is Ice.Unset) + test(ex.b is Ice.Unset) + test(ex.o is Ice.Unset) + + try: + initial.opDerivedException(Ice.Unset, Ice.Unset, Ice.Unset) + except Test.DerivedException as ex: + test(ex.a is Ice.Unset) + test(ex.b is Ice.Unset) + test(ex.o is Ice.Unset) + test(ex.ss is Ice.Unset) + test(ex.o2 is Ice.Unset) + + try: + initial.opDerivedException(30, "test2", Test.OneOptional(53)) + except Test.DerivedException as ex: + test(ex.a == 30) + test(ex.b == "test2") + test(ex.o.a == 53) + test(ex.ss == "test2") + test(ex.o2 == ex.o) + + try: + initial.opRequiredException(Ice.Unset, Ice.Unset, Ice.Unset) + except Test.RequiredException as ex: + test(ex.a is Ice.Unset) + test(ex.b is Ice.Unset) + test(ex.o is Ice.Unset) + test(ex.ss == "test") + test(ex.o2 == None) + + try: + initial.opRequiredException(30, "test2", Test.OneOptional(53)) + except Test.RequiredException as ex: + test(ex.a == 30) + test(ex.b == "test2") + test(ex.o.a == 53) + test(ex.ss == "test2") + test(ex.o2 == ex.o) + + print("ok") + + return initial diff --git a/python/test/Ice/optional/Client.py b/python/test/Ice/optional/Client.py new file mode 100755 index 00000000000..98b5a22d66f --- /dev/null +++ b/python/test/Ice/optional/Client.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('--all -I. ClientPrivate.ice') +import AllTests + +def run(args, communicator): + initial = AllTests.allTests(communicator) + initial.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/optional/ClientPrivate.ice b/python/test/Ice/optional/ClientPrivate.ice new file mode 100644 index 00000000000..c7211442401 --- /dev/null +++ b/python/test/Ice/optional/ClientPrivate.ice @@ -0,0 +1,37 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +// +// The server doesn't know this class. +// +class D extends B +{ + string ds; + optional(990) StringSeq seq; + optional(1000) A ao; +}; + +// +// This class is a hack that allows us to invoke the opClassAndUnknownOptional operation +// on the server and pass an optional argument. This isn't necessary in other language +// mappings where the public stream API is available. +// +class Initial2 +{ + void opClassAndUnknownOptional(A p, optional(1) Object o); +}; + +}; diff --git a/python/test/Ice/optional/Server.py b/python/test/Ice/optional/Server.py new file mode 100755 index 00000000000..1533bd38b70 --- /dev/null +++ b/python/test/Ice/optional/Server.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('Test.ice') +import Test + +class InitialI(Test.Initial): + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def pingPong(self, o, current=None): + return o + + def opOptionalException(self, a, b, o, current=None): + raise Test.OptionalException(False, a, b, o) + + def opDerivedException(self, a, b, o, current=None): + raise Test.DerivedException(False, a, b, o, b, o) + + def opRequiredException(self, a, b, o, current=None): + e = Test.RequiredException() + e.a = a + e.b = b + e.o = o + if b is not Ice.Unset: + e.ss = b + if o is not Ice.Unset: + e.o2 = o + raise e + + def opByte(self, p1, current=None): + return (p1, p1) + + def opBool(self, p1, current=None): + return (p1, p1) + + def opShort(self, p1, current=None): + return (p1, p1) + + def opInt(self, p1, current=None): + return (p1, p1) + + def opLong(self, p1, current=None): + return (p1, p1) + + def opFloat(self, p1, current=None): + return (p1, p1) + + def opDouble(self, p1, current=None): + return (p1, p1) + + def opString(self, p1, current=None): + return (p1, p1) + + def opMyEnum(self, p1, current=None): + return (p1, p1) + + def opSmallStruct(self, p1, current=None): + return (p1, p1) + + def opFixedStruct(self, p1, current=None): + return (p1, p1) + + def opVarStruct(self, p1, current=None): + return (p1, p1) + + def opOneOptional(self, p1, current=None): + return (p1, p1) + + def opOneOptionalProxy(self, p1, current=None): + return (p1, p1) + + def opByteSeq(self, p1, current=None): + return (p1, p1) + + def opBoolSeq(self, p1, current=None): + return (p1, p1) + + def opShortSeq(self, p1, current=None): + return (p1, p1) + + def opIntSeq(self, p1, current=None): + return (p1, p1) + + def opLongSeq(self, p1, current=None): + return (p1, p1) + + def opFloatSeq(self, p1, current=None): + return (p1, p1) + + def opDoubleSeq(self, p1, current=None): + return (p1, p1) + + def opStringSeq(self, p1, current=None): + return (p1, p1) + + def opSmallStructSeq(self, p1, current=None): + return (p1, p1) + + def opSmallStructList(self, p1, current=None): + return (p1, p1) + + def opFixedStructSeq(self, p1, current=None): + return (p1, p1) + + def opFixedStructList(self, p1, current=None): + return (p1, p1) + + def opVarStructSeq(self, p1, current=None): + return (p1, p1) + + def opSerializable(self, p1, current=None): + return (p1, p1) + + def opIntIntDict(self, p1, current=None): + return (p1, p1) + + def opStringIntDict(self, p1, current=None): + return (p1, p1) + + def opClassAndUnknownOptional(self, p, current=None): + pass + + def sendOptionalClass(self, req, o, current=None): + pass + + def returnOptionalClass(self, req, current=None): + return Test.OneOptional(5) + + def supportsRequiredParams(self, current=None): + return False + + def supportsJavaSerializable(self, current=None): + return True + + def supportsCsharpSerializable(self, current=None): + return True + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + initial = InitialI() + adapter.add(initial, communicator.stringToIdentity("initial")) + adapter.activate() + + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/optional/ServerAMD.py b/python/test/Ice/optional/ServerAMD.py new file mode 100755 index 00000000000..edf6701cb0e --- /dev/null +++ b/python/test/Ice/optional/ServerAMD.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('TestAMD.ice') +import Test + +class InitialI(Test.Initial): + + def shutdown_async(self, cb, current=None): + current.adapter.getCommunicator().shutdown() + cb.ice_response() + + def pingPong_async(self, cb, o, current=None): + cb.ice_response(o) + + def opOptionalException_async(self, cb, a, b, o, current=None): + cb.ice_exception(Test.OptionalException(False, a, b, o)) + + def opDerivedException_async(self, cb, a, b, o, current=None): + cb.ice_exception(Test.DerivedException(False, a, b, o, b, o)) + + def opRequiredException_async(self, cb, a, b, o, current=None): + e = Test.RequiredException() + e.a = a + e.b = b + e.o = o + if b is not Ice.Unset: + e.ss = b + if o is not Ice.Unset: + e.o2 = o + cb.ice_exception(e) + + def opByte_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opBool_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opShort_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opInt_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opLong_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opFloat_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opDouble_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opString_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opMyEnum_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opSmallStruct_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opFixedStruct_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opVarStruct_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opOneOptional_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opOneOptionalProxy_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opByteSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opBoolSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opShortSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opIntSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opLongSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opFloatSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opDoubleSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opStringSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opSmallStructSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opSmallStructList_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opFixedStructSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opFixedStructList_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opVarStructSeq_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opSerializable(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opIntIntDict_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opStringIntDict_async(self, cb, p1, current=None): + cb.ice_response(p1, p1) + + def opClassAndUnknownOptional_async(self, cb, p, current=None): + cb.ice_response() + + def sendOptionalClass_async(self, cb, req, o, current=None): + cb.ice_response() + + def returnOptionalClass_async(self, cb, req, current=None): + cb.ice_response(Test.OneOptional(5)) + + def supportsRequiredParams_async(self, cb, current=None): + cb.ice_response(False) + + def supportsJavaSerializable(self, cb, current=None): + cb.ice_response(True) + + def supportsCsharpSerializable(self, cb, current=None): + cb.ice_response(True) + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + initial = InitialI() + adapter.add(initial, communicator.stringToIdentity("initial")) + adapter.activate() + + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/optional/Test.ice b/python/test/Ice/optional/Test.ice new file mode 100644 index 00000000000..2a3d25720b6 --- /dev/null +++ b/python/test/Ice/optional/Test.ice @@ -0,0 +1,269 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class OneOptional +{ + optional(1) int a; +}; + +enum MyEnum +{ + MyEnumMember +}; + +struct SmallStruct +{ + byte m; +}; + +struct FixedStruct +{ + int m; +}; + +struct VarStruct +{ + string m; +}; + +struct ClassVarStruct +{ + int a; +}; + +sequence<byte> ByteSeq; +sequence<bool> BoolSeq; +sequence<short> ShortSeq; +sequence<int> IntSeq; +sequence<long> LongSeq; +sequence<float> FloatSeq; +sequence<double> DoubleSeq; +sequence<string> StringSeq; +sequence<MyEnum> MyEnumSeq; +sequence<SmallStruct> SmallStructSeq; +["python:seq:tuple"] sequence<SmallStruct> SmallStructList; +sequence<FixedStruct> FixedStructSeq; +["python:seq:tuple"] sequence<FixedStruct> FixedStructList; +sequence<VarStruct> VarStructSeq; +sequence<OneOptional> OneOptionalSeq; +sequence<OneOptional*> OneOptionalPrxSeq; + +sequence<byte> Serializable; + +dictionary<int, int> IntIntDict; +dictionary<string, int> StringIntDict; +dictionary<int, MyEnum> IntEnumDict; +dictionary<int, FixedStruct> IntFixedStructDict; +dictionary<int, VarStruct> IntVarStructDict; +dictionary<int, OneOptional> IntOneOptionalDict; +dictionary<int, OneOptional*> IntOneOptionalPrxDict; + +class MultiOptional +{ + optional(1) byte a; + optional(2) bool b; + optional(3) short c; + optional(4) int d; + optional(5) long e; + optional(6) float f; + optional(7) double g; + optional(8) string h; + optional(9) MyEnum i; + optional(10) MultiOptional* j; + optional(11) MultiOptional k; + optional(12) ByteSeq bs; + optional(13) StringSeq ss; + optional(14) IntIntDict iid; + optional(15) StringIntDict sid; + optional(16) FixedStruct fs; + optional(17) VarStruct vs; + + optional(18) ShortSeq shs; + optional(19) MyEnumSeq es; + optional(20) FixedStructSeq fss; + optional(21) VarStructSeq vss; + optional(22) OneOptionalSeq oos; + optional(23) OneOptionalPrxSeq oops; + + optional(24) IntEnumDict ied; + optional(25) IntFixedStructDict ifsd; + optional(26) IntVarStructDict ivsd; + optional(27) IntOneOptionalDict iood; + optional(28) IntOneOptionalPrxDict ioopd; + + optional(29) BoolSeq bos; + + optional(30) Serializable ser; +}; + +class A +{ + int requiredA; + optional(1) int ma; + optional(50) int mb; + optional(500) int mc; +}; + +["preserve-slice"] +class B extends A +{ + int requiredB; + optional(10) int md; +}; + +class C extends B +{ + string ss; + optional(890) string ms; +}; + +class WD +{ + optional(1) int a = 5; + optional(2) string s = "test"; +}; + +exception OptionalException +{ + bool req = false; + optional(1) int a = 5; + optional(2) string b; + optional(50) OneOptional o; +}; + +exception DerivedException extends OptionalException +{ + optional(600) string ss = "test"; + optional(601) OneOptional o2; +}; + +exception RequiredException extends OptionalException +{ + string ss = "test"; + OneOptional o2; +}; + +class OptionalWithCustom +{ + optional(1) SmallStructList l; + ["protected"] optional(2) SmallStructList lp; + optional(3) ClassVarStruct s; +}; + +class E +{ + A ae; +}; + +class F extends E +{ + optional(1) A af; +}; + +class Recursive; +sequence<Recursive> RecursiveSeq; + +class Recursive { + optional(0) RecursiveSeq value; +}; + +class Initial +{ + void shutdown(); + + Object pingPong(Object o); + + void opOptionalException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opDerivedException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opRequiredException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + optional(1) byte opByte(optional(2) byte p1, out optional(3) byte p3); + + optional(1) bool opBool(optional(2) bool p1, out optional(3) bool p3); + + optional(1) short opShort(optional(2) short p1, out optional(3) short p3); + + optional(1) int opInt(optional(2) int p1, out optional(3) int p3); + + optional(3) long opLong(optional(1) long p1, out optional(2) long p3); + + optional(1) float opFloat(optional(2) float p1, out optional(3) float p3); + + optional(1) double opDouble(optional(2) double p1, out optional(3) double p3); + + optional(1) string opString(optional(2) string p1, out optional(3) string p3); + + optional(1) MyEnum opMyEnum(optional(2) MyEnum p1, out optional(3) MyEnum p3); + + optional(1) SmallStruct opSmallStruct(optional(2) SmallStruct p1, out optional(3) SmallStruct p3); + + optional(1) FixedStruct opFixedStruct(optional(2) FixedStruct p1, out optional(3) FixedStruct p3); + + optional(1) VarStruct opVarStruct(optional(2) VarStruct p1, out optional(3) VarStruct p3); + + optional(1) OneOptional opOneOptional(optional(2) OneOptional p1, out optional(3) OneOptional p3); + + optional(1) OneOptional* opOneOptionalProxy(optional(2) OneOptional* p1, out optional(3) OneOptional* p3); + + optional(1) ByteSeq opByteSeq(optional(2) ByteSeq p1, out optional(3) ByteSeq p3); + + optional(1) BoolSeq opBoolSeq(optional(2) BoolSeq p1, out optional(3) BoolSeq p3); + + optional(1) ShortSeq opShortSeq(optional(2) ShortSeq p1, out optional(3) ShortSeq p3); + + optional(1) IntSeq opIntSeq(optional(2) IntSeq p1, out optional(3) IntSeq p3); + + optional(1) LongSeq opLongSeq(optional(2) LongSeq p1, out optional(3) LongSeq p3); + + optional(1) FloatSeq opFloatSeq(optional(2) FloatSeq p1, out optional(3) FloatSeq p3); + + optional(1) DoubleSeq opDoubleSeq(optional(2) DoubleSeq p1, out optional(3) DoubleSeq p3); + + optional(1) StringSeq opStringSeq(optional(2) StringSeq p1, out optional(3) StringSeq p3); + + optional(1) SmallStructSeq opSmallStructSeq(optional(2) SmallStructSeq p1, out optional(3) SmallStructSeq p3); + + optional(1) SmallStructList opSmallStructList(optional(2) SmallStructList p1, out optional(3) SmallStructList p3); + + optional(1) FixedStructSeq opFixedStructSeq(optional(2) FixedStructSeq p1, out optional(3) FixedStructSeq p3); + + optional(1) FixedStructList opFixedStructList(optional(2) FixedStructList p1, out optional(3) FixedStructList p3); + + optional(1) VarStructSeq opVarStructSeq(optional(2) VarStructSeq p1, out optional(3) VarStructSeq p3); + + optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3); + + optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3); + + optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3); + + void opClassAndUnknownOptional(A p); + + void sendOptionalClass(bool req, optional(1) OneOptional o); + + void returnOptionalClass(bool req, out optional(1) OneOptional o); + + bool supportsRequiredParams(); + + bool supportsJavaSerializable(); + + bool supportsCsharpSerializable(); +}; + +}; diff --git a/python/test/Ice/optional/TestAMD.ice b/python/test/Ice/optional/TestAMD.ice new file mode 100644 index 00000000000..cf6c62ee7f1 --- /dev/null +++ b/python/test/Ice/optional/TestAMD.ice @@ -0,0 +1,270 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class OneOptional +{ + optional(1) int a; +}; + +enum MyEnum +{ + MyEnumMember +}; + +struct SmallStruct +{ + byte m; +}; + +struct FixedStruct +{ + int m; +}; + +struct VarStruct +{ + string m; +}; + +struct ClassVarStruct +{ + int a; +}; + +sequence<byte> ByteSeq; +sequence<bool> BoolSeq; +sequence<short> ShortSeq; +sequence<int> IntSeq; +sequence<long> LongSeq; +sequence<float> FloatSeq; +sequence<double> DoubleSeq; +sequence<string> StringSeq; +sequence<MyEnum> MyEnumSeq; +sequence<SmallStruct> SmallStructSeq; +["python:seq:tuple"] sequence<SmallStruct> SmallStructList; +sequence<FixedStruct> FixedStructSeq; +["python:seq:tuple"] sequence<FixedStruct> FixedStructList; +sequence<VarStruct> VarStructSeq; +sequence<OneOptional> OneOptionalSeq; +sequence<OneOptional*> OneOptionalPrxSeq; + +sequence<byte> Serializable; + +dictionary<int, int> IntIntDict; +dictionary<string, int> StringIntDict; +dictionary<int, MyEnum> IntEnumDict; +dictionary<int, FixedStruct> IntFixedStructDict; +dictionary<int, VarStruct> IntVarStructDict; +dictionary<int, OneOptional> IntOneOptionalDict; +dictionary<int, OneOptional*> IntOneOptionalPrxDict; + +class MultiOptional +{ + optional(1) byte a; + optional(2) bool b; + optional(3) short c; + optional(4) int d; + optional(5) long e; + optional(6) float f; + optional(7) double g; + optional(8) string h; + optional(9) MyEnum i; + optional(10) MultiOptional* j; + optional(11) MultiOptional k; + optional(12) ByteSeq bs; + optional(13) StringSeq ss; + optional(14) IntIntDict iid; + optional(15) StringIntDict sid; + optional(16) FixedStruct fs; + optional(17) VarStruct vs; + + optional(18) ShortSeq shs; + optional(19) MyEnumSeq es; + optional(20) FixedStructSeq fss; + optional(21) VarStructSeq vss; + optional(22) OneOptionalSeq oos; + optional(23) OneOptionalPrxSeq oops; + + optional(24) IntEnumDict ied; + optional(25) IntFixedStructDict ifsd; + optional(26) IntVarStructDict ivsd; + optional(27) IntOneOptionalDict iood; + optional(28) IntOneOptionalPrxDict ioopd; + + optional(29) BoolSeq bos; + + optional(30) Serializable ser; +}; + +class A +{ + int requiredA; + optional(1) int ma; + optional(50) int mb; + optional(500) int mc; +}; + +["preserve-slice"] +class B extends A +{ + int requiredB; + optional(10) int md; +}; + +class C extends B +{ + string ss; + optional(890) string ms; +}; + +class WD +{ + optional(1) int a = 5; + optional(2) string s = "test"; +}; + +exception OptionalException +{ + bool req = false; + optional(1) int a = 5; + optional(2) string b; + optional(50) OneOptional o; +}; + +exception DerivedException extends OptionalException +{ + optional(600) string ss = "test"; + optional(601) OneOptional o2; +}; + +exception RequiredException extends OptionalException +{ + string ss = "test"; + OneOptional o2; +}; + +class OptionalWithCustom +{ + optional(1) SmallStructList l; + ["protected"] optional(2) SmallStructList lp; + optional(3) ClassVarStruct s; +}; + +class E +{ + A ae; +}; + +class F extends E +{ + optional(1) A af; +}; + +class Recursive; +sequence<Recursive> RecursiveSeq; + +class Recursive { + optional(0) RecursiveSeq value; +}; + +["amd"] +class Initial +{ + void shutdown(); + + Object pingPong(Object o); + + void opOptionalException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opDerivedException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + void opRequiredException(optional(1) int a, optional(2) string b, optional(3) OneOptional o) + throws OptionalException; + + optional(1) byte opByte(optional(2) byte p1, out optional(3) byte p3); + + optional(1) bool opBool(optional(2) bool p1, out optional(3) bool p3); + + optional(1) short opShort(optional(2) short p1, out optional(3) short p3); + + optional(1) int opInt(optional(2) int p1, out optional(3) int p3); + + optional(3) long opLong(optional(1) long p1, out optional(2) long p3); + + optional(1) float opFloat(optional(2) float p1, out optional(3) float p3); + + optional(1) double opDouble(optional(2) double p1, out optional(3) double p3); + + optional(1) string opString(optional(2) string p1, out optional(3) string p3); + + optional(1) MyEnum opMyEnum(optional(2) MyEnum p1, out optional(3) MyEnum p3); + + optional(1) SmallStruct opSmallStruct(optional(2) SmallStruct p1, out optional(3) SmallStruct p3); + + optional(1) FixedStruct opFixedStruct(optional(2) FixedStruct p1, out optional(3) FixedStruct p3); + + optional(1) VarStruct opVarStruct(optional(2) VarStruct p1, out optional(3) VarStruct p3); + + optional(1) OneOptional opOneOptional(optional(2) OneOptional p1, out optional(3) OneOptional p3); + + optional(1) OneOptional* opOneOptionalProxy(optional(2) OneOptional* p1, out optional(3) OneOptional* p3); + + optional(1) ByteSeq opByteSeq(optional(2) ByteSeq p1, out optional(3) ByteSeq p3); + + optional(1) BoolSeq opBoolSeq(optional(2) BoolSeq p1, out optional(3) BoolSeq p3); + + optional(1) ShortSeq opShortSeq(optional(2) ShortSeq p1, out optional(3) ShortSeq p3); + + optional(1) IntSeq opIntSeq(optional(2) IntSeq p1, out optional(3) IntSeq p3); + + optional(1) LongSeq opLongSeq(optional(2) LongSeq p1, out optional(3) LongSeq p3); + + optional(1) FloatSeq opFloatSeq(optional(2) FloatSeq p1, out optional(3) FloatSeq p3); + + optional(1) DoubleSeq opDoubleSeq(optional(2) DoubleSeq p1, out optional(3) DoubleSeq p3); + + optional(1) StringSeq opStringSeq(optional(2) StringSeq p1, out optional(3) StringSeq p3); + + optional(1) SmallStructSeq opSmallStructSeq(optional(2) SmallStructSeq p1, out optional(3) SmallStructSeq p3); + + optional(1) SmallStructList opSmallStructList(optional(2) SmallStructList p1, out optional(3) SmallStructList p3); + + optional(1) FixedStructSeq opFixedStructSeq(optional(2) FixedStructSeq p1, out optional(3) FixedStructSeq p3); + + optional(1) FixedStructList opFixedStructList(optional(2) FixedStructList p1, out optional(3) FixedStructList p3); + + optional(1) VarStructSeq opVarStructSeq(optional(2) VarStructSeq p1, out optional(3) VarStructSeq p3); + + optional(1) Serializable opSerializable(optional(2) Serializable p1, out optional(3) Serializable p3); + + optional(1) IntIntDict opIntIntDict(optional(2) IntIntDict p1, out optional(3) IntIntDict p3); + + optional(1) StringIntDict opStringIntDict(optional(2) StringIntDict p1, out optional(3) StringIntDict p3); + + void opClassAndUnknownOptional(A p); + + void sendOptionalClass(bool req, optional(1) OneOptional o); + + void returnOptionalClass(bool req, out optional(1) OneOptional o); + + bool supportsRequiredParams(); + + bool supportsJavaSerializable(); + + bool supportsCsharpSerializable(); +}; + +}; diff --git a/python/test/Ice/optional/run.py b/python/test/Ice/optional/run.py new file mode 100755 index 00000000000..1a3f97ec2e2 --- /dev/null +++ b/python/test/Ice/optional/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with compact (default) format.") +TestUtil.clientServerTest() +print("Running test with sliced format.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.SlicedFormat", additionalServerOptions="--Ice.Default.SlicedFormat") +print("Running test with AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") diff --git a/python/test/Ice/properties/Client.py b/python/test/Ice/properties/Client.py new file mode 100644 index 00000000000..e771da6903e --- /dev/null +++ b/python/test/Ice/properties/Client.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + + +import os, sys, traceback +import Ice + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class Client(Ice.Application): + def run(self, args): + properties = self.communicator().getProperties() + test(properties.getProperty("Ice.Trace.Network") == "1") + test(properties.getProperty("Ice.Trace.Protocol") == "1") + test(properties.getProperty("Config.Path") == "./config/ä¸å›½_client.config") + test(properties.getProperty("Ice.ProgramName") == "PropertiesClient") + test(self.appName() == properties.getProperty("Ice.ProgramName")) + + +sys.stdout.write("testing load properties from UTF-8 path... ") +sys.stdout.flush() +properties = Ice.createProperties() +properties.load("./config/ä¸å›½_client.config") +test(properties.getProperty("Ice.Trace.Network") == "1") +test(properties.getProperty("Ice.Trace.Protocol") == "1") +test(properties.getProperty("Config.Path") == "./config/ä¸å›½_client.config") +test(properties.getProperty("Ice.ProgramName") == "PropertiesClient") +print("ok") +sys.stdout.write("testing load properties from UTF-8 path using Ice::Application... ") +sys.stdout.flush() +c = Client() +c.main(sys.argv, "./config/ä¸å›½_client.config") +print("ok") + +sys.stdout.write("testing using Ice.Config with multiple config files... ") +sys.stdout.flush() +properties = Ice.createProperties(["--Ice.Config=config/config.1, config/config.2, config/config.3"]) +test(properties.getProperty("Config1") == "Config1") +test(properties.getProperty("Config2") == "Config2") +test(properties.getProperty("Config3") == "Config3") +print("ok") + +sys.stdout.write("testing configuration file escapes... ") +sys.stdout.flush() +properties = Ice.createProperties(["--Ice.Config=config/escapes.cfg"]) + +props = { "Foo\tBar":"3", + "Foo\\tBar":"4", + "Escape\\ Space":"2", + "Prop1":"1", + "Prop2":"2", + "Prop3":"3", + "My Prop1":"1", + "My Prop2":"2", + "My.Prop1":"a property", + "My.Prop2":"a property", + "My.Prop3":" a property ", + "My.Prop4":" a property ", + "My.Prop5":"a \\ property", + "foo=bar":"1", + "foo#bar":"2", + "foo bar":"3", + "A":"1", + "B":"2 3 4", + "C":"5=#6", + "AServer":"\\\\server\\dir", + "BServer":"\\server\\dir"}; + +for k in props.keys(): + test(properties.getProperty(k) == props[k]) + +print("ok") + +sys.exit(0) diff --git a/python/test/Ice/properties/config/.gitignore b/python/test/Ice/properties/config/.gitignore new file mode 100644 index 00000000000..143c64680f3 --- /dev/null +++ b/python/test/Ice/properties/config/.gitignore @@ -0,0 +1 @@ +*.config diff --git a/python/test/Ice/properties/config/config.1 b/python/test/Ice/properties/config/config.1 new file mode 100644 index 00000000000..2a20653e4c5 --- /dev/null +++ b/python/test/Ice/properties/config/config.1 @@ -0,0 +1 @@ +Config1=Config1
\ No newline at end of file diff --git a/python/test/Ice/properties/config/config.2 b/python/test/Ice/properties/config/config.2 new file mode 100644 index 00000000000..be276df6602 --- /dev/null +++ b/python/test/Ice/properties/config/config.2 @@ -0,0 +1 @@ +Config2=Config2
\ No newline at end of file diff --git a/python/test/Ice/properties/config/config.3 b/python/test/Ice/properties/config/config.3 new file mode 100644 index 00000000000..55c1e1123f6 --- /dev/null +++ b/python/test/Ice/properties/config/config.3 @@ -0,0 +1 @@ +Config3=Config3
\ No newline at end of file diff --git a/python/test/Ice/properties/config/escapes.cfg b/python/test/Ice/properties/config/escapes.cfg new file mode 100644 index 00000000000..f438d2b59c8 --- /dev/null +++ b/python/test/Ice/properties/config/escapes.cfg @@ -0,0 +1,35 @@ +Foo Bar=3 #tab +Foo\tBar=4 # embedded\t +Escape\\ Space=2 + +# +# From Ice manual: +# + +Prop1 = 1 # Key is "Prop1" + Prop2 = 2 # Key is "Prop2" +\ Prop3 \ = 3 # Key is "Prop3" +My Prop1 = 1 # Key is "My Prop1" +My\ Prop2 = 2 # Key is "My Prop2" + +My.Prop1 = a property # Value is "a property" +My.Prop2 = a property # Value is "a property" +My.Prop3 = \ \ a property\ \ # Value is " a property " +My.Prop4 = \ \ a \ \ property\ \ # Value is " a property " +My.Prop5 = a \\ property # Value is "a \ property" + +foo\=bar=1 # Name is "foo=bar", value is "1" +foo\#bar = 2 # Name is "foo#bar", value is "2" +foo bar =3 # Name is "foo bar", value is "3" + + +A=1 # Name is "A", value is "1" +B= 2 3 4 # Name is "B", value is "2 3 4" +C=5=\#6 # 7 # Name is "C", value is "5=#6" + +AServer=\\\\server\dir # Value is "\\server\dir" +BServer=\\server\\dir # Value is "\server\dir" + + + + diff --git a/python/test/Ice/properties/run.py b/python/test/Ice/properties/run.py new file mode 100755 index 00000000000..c6ce2b8cfad --- /dev/null +++ b/python/test/Ice/properties/run.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +# +# Write config +# +if sys.version_info[0] == 2: + configPath = "./config/\xe4\xb8\xad\xe5\x9b\xbd_client.config" +else: + configPath = "./config/\u4e2d\u56fd_client.config" + +TestUtil.createConfig(configPath, + ["# Automatically generated by Ice test driver.", + "Ice.Trace.Protocol=1", + "Ice.Trace.Network=1", + "Ice.ProgramName=PropertiesClient", + "Config.Path=" + configPath], + "utf-8") + +TestUtil.simpleTest() + +if os.path.exists(configPath): + os.remove(configPath) diff --git a/python/test/Ice/proxy/AllTests.py b/python/test/Ice/proxy/AllTests.py new file mode 100644 index 00000000000..fb606824b30 --- /dev/null +++ b/python/test/Ice/proxy/AllTests.py @@ -0,0 +1,785 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator, collocated): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + + # + # Test nil proxies. + # + p = communicator.stringToProxy('') + test(p == None) + p = communicator.propertyToProxy('bogus') + test(p == None) + + ref = "test:default -p 12010" + base = communicator.stringToProxy(ref) + test(base) + + b1 = communicator.stringToProxy("test") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getAdapterId()) == 0 and len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy("test ") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy(" test ") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy(" test") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy("'test -f facet'") + test(b1.ice_getIdentity().name == "test -f facet" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + try: + b1 = communicator.stringToProxy("\"test -f facet'") + test(False) + except Ice.ProxyParseException: + pass + b1 = communicator.stringToProxy("\"test -f facet\"") + test(b1.ice_getIdentity().name == "test -f facet" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy("\"test -f facet@test\"") + test(b1.ice_getIdentity().name == "test -f facet@test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + b1 = communicator.stringToProxy("\"test -f facet@test @test\"") + test(b1.ice_getIdentity().name == "test -f facet@test @test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getFacet()) == 0) + try: + b1 = communicator.stringToProxy("test test") + test(False) + except Ice.ProxyParseException: + pass + b1 = communicator.stringToProxy("test\\040test") + test(b1.ice_getIdentity().name == "test test" and len(b1.ice_getIdentity().category) == 0) + try: + b1 = communicator.stringToProxy("test\\777") + test(False) + except Ice.IdentityParseException: + pass + b1 = communicator.stringToProxy("test\\40test") + test(b1.ice_getIdentity().name == "test test") + + # Test some octal and hex corner cases. + b1 = communicator.stringToProxy("test\\4test") + test(b1.ice_getIdentity().name == "test\4test") + b1 = communicator.stringToProxy("test\\04test") + test(b1.ice_getIdentity().name == "test\4test") + b1 = communicator.stringToProxy("test\\004test") + test(b1.ice_getIdentity().name == "test\4test") + b1 = communicator.stringToProxy("test\\1114test") + test(b1.ice_getIdentity().name == "test\1114test") + + b1 = communicator.stringToProxy("test\\b\\f\\n\\r\\t\\'\\\"\\\\test") + test(b1.ice_getIdentity().name == "test\b\f\n\r\t\'\"\\test" and len(b1.ice_getIdentity().category) == 0) + + b1 = communicator.stringToProxy("category/test") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category" and \ + len(b1.ice_getAdapterId()) == 0) + + b1 = communicator.stringToProxy("test@adapter") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getAdapterId() == "adapter") + try: + b1 = communicator.stringToProxy("id@adapter test") + test(False) + except Ice.ProxyParseException: + pass + b1 = communicator.stringToProxy("category/test@adapter") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category" and \ + b1.ice_getAdapterId() == "adapter") + b1 = communicator.stringToProxy("category/test@adapter:tcp") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category" and \ + b1.ice_getAdapterId() == "adapter:tcp") + b1 = communicator.stringToProxy("'category 1/test'@adapter") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category 1" and \ + b1.ice_getAdapterId() == "adapter") + b1 = communicator.stringToProxy("'category/test 1'@adapter") + test(b1.ice_getIdentity().name == "test 1" and b1.ice_getIdentity().category == "category" and \ + b1.ice_getAdapterId() == "adapter") + b1 = communicator.stringToProxy("'category/test'@'adapter 1'") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category" and \ + b1.ice_getAdapterId() == "adapter 1") + b1 = communicator.stringToProxy("\"category \\/test@foo/test\"@adapter") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category /test@foo" and \ + b1.ice_getAdapterId() == "adapter") + b1 = communicator.stringToProxy("\"category \\/test@foo/test\"@\"adapter:tcp\"") + test(b1.ice_getIdentity().name == "test" and b1.ice_getIdentity().category == "category /test@foo" and \ + b1.ice_getAdapterId() == "adapter:tcp") + + b1 = communicator.stringToProxy("id -f facet") + test(b1.ice_getIdentity().name == "id" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet") + b1 = communicator.stringToProxy("id -f 'facet x'") + test(b1.ice_getIdentity().name == "id" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet x") + b1 = communicator.stringToProxy("id -f \"facet x\"") + test(b1.ice_getIdentity().name == "id" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet x") + try: + b1 = communicator.stringToProxy("id -f \"facet x") + test(False) + except Ice.ProxyParseException: + pass + try: + b1 = communicator.stringToProxy("id -f \'facet x") + test(False) + except Ice.ProxyParseException: + pass + b1 = communicator.stringToProxy("test -f facet:tcp") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet" and len(b1.ice_getAdapterId()) == 0) + b1 = communicator.stringToProxy("test -f \"facet:tcp\"") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet:tcp" and len(b1.ice_getAdapterId()) == 0) + b1 = communicator.stringToProxy("test -f facet@test") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet" and b1.ice_getAdapterId() == "test") + b1 = communicator.stringToProxy("test -f 'facet@test'") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet@test" and len(b1.ice_getAdapterId()) == 0) + b1 = communicator.stringToProxy("test -f 'facet@test'@test") + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + b1.ice_getFacet() == "facet@test" and b1.ice_getAdapterId() == "test") + try: + b1 = communicator.stringToProxy("test -f facet@test @test") + test(False) + except Ice.ProxyParseException: + pass + b1 = communicator.stringToProxy("test") + test(b1.ice_isTwoway()) + b1 = communicator.stringToProxy("test -t") + test(b1.ice_isTwoway()) + b1 = communicator.stringToProxy("test -o") + test(b1.ice_isOneway()) + b1 = communicator.stringToProxy("test -O") + test(b1.ice_isBatchOneway()) + b1 = communicator.stringToProxy("test -d") + test(b1.ice_isDatagram()) + b1 = communicator.stringToProxy("test -D") + test(b1.ice_isBatchDatagram()) + b1 = communicator.stringToProxy("test") + test(not b1.ice_isSecure()) + b1 = communicator.stringToProxy("test -s") + test(b1.ice_isSecure()) + + try: + b1 = communicator.stringToProxy("test:tcp@adapterId") + test(False) + except Ice.EndpointParseException: + pass + # This is an unknown endpoint warning, not a parse exception. + # + #try: + # b1 = communicator.stringToProxy("test -f the:facet:tcp") + # test(False) + #except Ice.EndpointParseException: + # pass + try: + b1 = communicator.stringToProxy("test::tcp") + test(False) + except Ice.EndpointParseException: + pass + print("ok") + + sys.stdout.write("testing propertyToProxy... ") + sys.stdout.flush() + prop = communicator.getProperties() + propertyPrefix = "Foo.Proxy" + prop.setProperty(propertyPrefix, "test:default -p 12010") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getIdentity().name == "test" and len(b1.ice_getIdentity().category) == 0 and \ + len(b1.ice_getAdapterId()) == 0 and len(b1.ice_getFacet()) == 0) + + property = propertyPrefix + ".Locator" + test(not b1.ice_getLocator()) + prop.setProperty(property, "locator:default -p 10000") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getLocator() and b1.ice_getLocator().ice_getIdentity().name == "locator") + prop.setProperty(property, "") + + property = propertyPrefix + ".LocatorCacheTimeout" + test(b1.ice_getLocatorCacheTimeout() == -1) + prop.setProperty(property, "1") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getLocatorCacheTimeout() == 1) + prop.setProperty(property, "") + + # Now retest with an indirect proxy. + prop.setProperty(propertyPrefix, "test") + property = propertyPrefix + ".Locator" + prop.setProperty(property, "locator:default -p 10000") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getLocator() and b1.ice_getLocator().ice_getIdentity().name == "locator") + prop.setProperty(property, "") + + property = propertyPrefix + ".LocatorCacheTimeout" + test(b1.ice_getLocatorCacheTimeout() == -1) + prop.setProperty(property, "1") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getLocatorCacheTimeout() == 1) + prop.setProperty(property, "") + + # This cannot be tested so easily because the property is cached + # on communicator initialization. + # + #prop.setProperty("Ice.Default.LocatorCacheTimeout", "60") + #b1 = communicator.propertyToProxy(propertyPrefix) + #test(b1.ice_getLocatorCacheTimeout() == 60) + #prop.setProperty("Ice.Default.LocatorCacheTimeout", "") + + prop.setProperty(propertyPrefix, "test:default -p 12010") + + property = propertyPrefix + ".Router" + test(not b1.ice_getRouter()) + prop.setProperty(property, "router:default -p 10000") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getRouter() and b1.ice_getRouter().ice_getIdentity().name == "router") + prop.setProperty(property, "") + + property = propertyPrefix + ".PreferSecure" + test(not b1.ice_isPreferSecure()) + prop.setProperty(property, "1") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_isPreferSecure()) + prop.setProperty(property, "") + + property = propertyPrefix + ".ConnectionCached" + test(b1.ice_isConnectionCached()) + prop.setProperty(property, "0") + b1 = communicator.propertyToProxy(propertyPrefix) + test(not b1.ice_isConnectionCached()) + prop.setProperty(property, "") + + property = propertyPrefix + ".InvocationTimeout"; + test(b1.ice_getInvocationTimeout() == -1); + prop.setProperty(property, "1000"); + b1 = communicator.propertyToProxy(propertyPrefix); + test(b1.ice_getInvocationTimeout() == 1000); + prop.setProperty(property, ""); + + property = propertyPrefix + ".EndpointSelection" + test(b1.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random) + prop.setProperty(property, "Random") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getEndpointSelection() == Ice.EndpointSelectionType.Random) + prop.setProperty(property, "Ordered") + b1 = communicator.propertyToProxy(propertyPrefix) + test(b1.ice_getEndpointSelection() == Ice.EndpointSelectionType.Ordered) + prop.setProperty(property, "") + property = propertyPrefix + ".CollocationOptimized" + test(b1.ice_isCollocationOptimized()) + prop.setProperty(property, "0") + b1 = communicator.propertyToProxy(propertyPrefix) + test(not b1.ice_isCollocationOptimized()) + prop.setProperty(property, "") + + print("ok") + + sys.stdout.write("testing proxyToProperty... ") + sys.stdout.flush() + + b1 = communicator.stringToProxy("test") + b1 = b1.ice_collocationOptimized(True) + b1 = b1.ice_connectionCached(True) + b1 = b1.ice_preferSecure(False) + b1 = b1.ice_endpointSelection(Ice.EndpointSelectionType.Ordered) + b1 = b1.ice_locatorCacheTimeout(100) + b1 = b1.ice_invocationTimeout(1234); + b1 = b1.ice_encodingVersion(Ice.EncodingVersion(1, 0)) + + router = communicator.stringToProxy("router") + router = router.ice_collocationOptimized(False) + router = router.ice_connectionCached(True) + router = router.ice_preferSecure(True) + router = router.ice_endpointSelection(Ice.EndpointSelectionType.Random) + router = router.ice_locatorCacheTimeout(200) + router = router.ice_invocationTimeout(1500); + + locator = communicator.stringToProxy("locator") + locator = locator.ice_collocationOptimized(True) + locator = locator.ice_connectionCached(False) + locator = locator.ice_preferSecure(True) + locator = locator.ice_endpointSelection(Ice.EndpointSelectionType.Random) + locator = locator.ice_locatorCacheTimeout(300) + locator = locator.ice_invocationTimeout(1500); + + locator = locator.ice_router(Ice.RouterPrx.uncheckedCast(router)) + b1 = b1.ice_locator(Ice.LocatorPrx.uncheckedCast(locator)) + + proxyProps = communicator.proxyToProperty(b1, "Test") + test(len(proxyProps) == 21) + + test(proxyProps["Test"] == "test -t -e 1.0") + test(proxyProps["Test.CollocationOptimized"] == "1") + test(proxyProps["Test.ConnectionCached"] == "1") + test(proxyProps["Test.PreferSecure"] == "0") + test(proxyProps["Test.EndpointSelection"] == "Ordered") + test(proxyProps["Test.LocatorCacheTimeout"] == "100") + test(proxyProps["Test.InvocationTimeout"] == "1234"); + + test(proxyProps["Test.Locator"] == "locator -t -e " + Ice.encodingVersionToString(Ice.currentEncoding())) + test(proxyProps["Test.Locator.CollocationOptimized"] == "1") + test(proxyProps["Test.Locator.ConnectionCached"] == "0") + test(proxyProps["Test.Locator.PreferSecure"] == "1") + test(proxyProps["Test.Locator.EndpointSelection"] == "Random") + test(proxyProps["Test.Locator.LocatorCacheTimeout"] == "300") + test(proxyProps["Test.Locator.InvocationTimeout"] == "1500"); + + test(proxyProps["Test.Locator.Router"] == "router -t -e " + Ice.encodingVersionToString(Ice.currentEncoding())) + test(proxyProps["Test.Locator.Router.CollocationOptimized"] == "0") + test(proxyProps["Test.Locator.Router.ConnectionCached"] == "1") + test(proxyProps["Test.Locator.Router.PreferSecure"] == "1") + test(proxyProps["Test.Locator.Router.EndpointSelection"] == "Random") + test(proxyProps["Test.Locator.Router.LocatorCacheTimeout"] == "200") + test(proxyProps["Test.Locator.Router.InvocationTimeout"] == "1500"); + + print("ok") + + sys.stdout.write("testing ice_getCommunicator... ") + sys.stdout.flush() + + test(base.ice_getCommunicator() == communicator) + + print("ok") + + sys.stdout.write("testing proxy methods... ") + sys.stdout.flush() + test(communicator.identityToString(base.ice_identity(communicator.stringToIdentity("other")).ice_getIdentity()) \ + == "other") + test(base.ice_facet("facet").ice_getFacet() == "facet") + test(base.ice_adapterId("id").ice_getAdapterId() == "id") + test(base.ice_twoway().ice_isTwoway()) + test(base.ice_oneway().ice_isOneway()) + test(base.ice_batchOneway().ice_isBatchOneway()) + test(base.ice_datagram().ice_isDatagram()) + test(base.ice_batchDatagram().ice_isBatchDatagram()) + test(base.ice_secure(True).ice_isSecure()) + test(not base.ice_secure(False).ice_isSecure()) + test(base.ice_collocationOptimized(True).ice_isCollocationOptimized()) + test(not base.ice_collocationOptimized(False).ice_isCollocationOptimized()) + test(base.ice_preferSecure(True).ice_isPreferSecure()) + test(not base.ice_preferSecure(False).ice_isPreferSecure()) + test(base.ice_encodingVersion(Ice.Encoding_1_0).ice_getEncodingVersion() == Ice.Encoding_1_0) + test(base.ice_encodingVersion(Ice.Encoding_1_1).ice_getEncodingVersion() == Ice.Encoding_1_1) + test(base.ice_encodingVersion(Ice.Encoding_1_0).ice_getEncodingVersion() != Ice.Encoding_1_1) + + try: + base.ice_timeout(0) + test(False) + except RuntimeError: + pass + + try: + base.ice_timeout(-1) + except RuntimeError: + test(False) + + try: + base.ice_timeout(-2) + test(False) + except RuntimeError: + pass + + try: + base.ice_invocationTimeout(0) + test(False) + except RuntimeError: + pass + + try: + base.ice_invocationTimeout(-1) + except RuntimeError: + test(False) + + try: + base.ice_invocationTimeout(-2) + test(False) + except RuntimeError: + pass + + try: + base.ice_locatorCacheTimeout(0) + except RuntimeError: + test(False) + + try: + base.ice_locatorCacheTimeout(-1) + except RuntimeError: + test(False) + + try: + base.ice_locatorCacheTimeout(-2) + test(False) + except RuntimeError: + pass + + print("ok") + + sys.stdout.write("testing proxy comparison... ") + sys.stdout.flush() + + test(communicator.stringToProxy("foo") == communicator.stringToProxy("foo")) + test(communicator.stringToProxy("foo") != communicator.stringToProxy("foo2")) + test(communicator.stringToProxy("foo") < communicator.stringToProxy("foo2")) + test(not (communicator.stringToProxy("foo2") < communicator.stringToProxy("foo"))) + + compObj = communicator.stringToProxy("foo") + + test(compObj.ice_facet("facet") == compObj.ice_facet("facet")) + test(compObj.ice_facet("facet") != compObj.ice_facet("facet1")) + test(compObj.ice_facet("facet") < compObj.ice_facet("facet1")) + test(not (compObj.ice_facet("facet") < compObj.ice_facet("facet"))) + + test(compObj.ice_oneway() == compObj.ice_oneway()) + test(compObj.ice_oneway() != compObj.ice_twoway()) + test(compObj.ice_twoway() < compObj.ice_oneway()) + test(not (compObj.ice_oneway() < compObj.ice_twoway())) + + test(compObj.ice_secure(True) == compObj.ice_secure(True)) + test(compObj.ice_secure(False) != compObj.ice_secure(True)) + test(compObj.ice_secure(False) < compObj.ice_secure(True)) + test(not (compObj.ice_secure(True) < compObj.ice_secure(False))) + + test(compObj.ice_collocationOptimized(True) == compObj.ice_collocationOptimized(True)) + test(compObj.ice_collocationOptimized(False) != compObj.ice_collocationOptimized(True)) + test(compObj.ice_collocationOptimized(False) < compObj.ice_collocationOptimized(True)) + test(not (compObj.ice_collocationOptimized(True) < compObj.ice_collocationOptimized(False))) + + test(compObj.ice_connectionCached(True) == compObj.ice_connectionCached(True)) + test(compObj.ice_connectionCached(False) != compObj.ice_connectionCached(True)) + test(compObj.ice_connectionCached(False) < compObj.ice_connectionCached(True)) + test(not (compObj.ice_connectionCached(True) < compObj.ice_connectionCached(False))) + + test(compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random) == \ + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random)) + test(compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random) != \ + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)) + test(compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random) < \ + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered)) + test(not (compObj.ice_endpointSelection(Ice.EndpointSelectionType.Ordered) < \ + compObj.ice_endpointSelection(Ice.EndpointSelectionType.Random))) + + test(compObj.ice_connectionId("id2") == compObj.ice_connectionId("id2")) + test(compObj.ice_connectionId("id1") != compObj.ice_connectionId("id2")) + test(compObj.ice_connectionId("id1") < compObj.ice_connectionId("id2")) + test(not (compObj.ice_connectionId("id2") < compObj.ice_connectionId("id1"))) + test(compObj.ice_connectionId("id1").ice_getConnectionId() == "id1") + test(compObj.ice_connectionId("id2").ice_getConnectionId() == "id2") + + test(compObj.ice_compress(True) == compObj.ice_compress(True)) + test(compObj.ice_compress(False) != compObj.ice_compress(True)) + test(compObj.ice_compress(False) < compObj.ice_compress(True)) + test(not (compObj.ice_compress(True) < compObj.ice_compress(False))) + + test(compObj.ice_timeout(20) == compObj.ice_timeout(20)) + test(compObj.ice_timeout(10) != compObj.ice_timeout(20)) + test(compObj.ice_timeout(10) < compObj.ice_timeout(20)) + test(not (compObj.ice_timeout(20) < compObj.ice_timeout(10))) + + loc1 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("loc1:default -p 10000")) + loc2 = Ice.LocatorPrx.uncheckedCast(communicator.stringToProxy("loc2:default -p 10000")) + test(compObj.ice_locator(None) == compObj.ice_locator(None)) + test(compObj.ice_locator(loc1) == compObj.ice_locator(loc1)) + test(compObj.ice_locator(loc1) != compObj.ice_locator(None)) + test(compObj.ice_locator(None) != compObj.ice_locator(loc2)) + test(compObj.ice_locator(loc1) != compObj.ice_locator(loc2)) + test(compObj.ice_locator(None) < compObj.ice_locator(loc1)) + test(not (compObj.ice_locator(loc1) < compObj.ice_locator(None))) + test(compObj.ice_locator(loc1) < compObj.ice_locator(loc2)) + test(not (compObj.ice_locator(loc2) < compObj.ice_locator(loc1))) + + rtr1 = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("rtr1:default -p 10000")) + rtr2 = Ice.RouterPrx.uncheckedCast(communicator.stringToProxy("rtr2:default -p 10000")) + test(compObj.ice_router(None) == compObj.ice_router(None)) + test(compObj.ice_router(rtr1) == compObj.ice_router(rtr1)) + test(compObj.ice_router(rtr1) != compObj.ice_router(None)) + test(compObj.ice_router(None) != compObj.ice_router(rtr2)) + test(compObj.ice_router(rtr1) != compObj.ice_router(rtr2)) + test(compObj.ice_router(None) < compObj.ice_router(rtr1)) + test(not (compObj.ice_router(rtr1) < compObj.ice_router(None))) + test(compObj.ice_router(rtr1) < compObj.ice_router(rtr2)) + test(not (compObj.ice_router(rtr2) < compObj.ice_router(rtr1))) + + ctx1 = { } + ctx1["ctx1"] = "v1" + ctx2 = { } + ctx2["ctx2"] = "v2" + test(compObj.ice_context({ }) == compObj.ice_context({ })) + test(compObj.ice_context(ctx1) == compObj.ice_context(ctx1)) + test(compObj.ice_context(ctx1) != compObj.ice_context({ })) + test(compObj.ice_context({ }) != compObj.ice_context(ctx2)) + test(compObj.ice_context(ctx1) != compObj.ice_context(ctx2)) + test(compObj.ice_context(ctx1) < compObj.ice_context(ctx2)) + test(not (compObj.ice_context(ctx2) < compObj.ice_context(ctx1))) + + test(compObj.ice_preferSecure(True) == compObj.ice_preferSecure(True)) + test(compObj.ice_preferSecure(True) != compObj.ice_preferSecure(False)) + test(compObj.ice_preferSecure(False) < compObj.ice_preferSecure(True)) + test(not (compObj.ice_preferSecure(True) < compObj.ice_preferSecure(False))) + + compObj1 = communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 10000") + compObj2 = communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 10001") + test(compObj1 != compObj2) + test(compObj1 < compObj2) + test(not (compObj2 < compObj1)) + + compObj1 = communicator.stringToProxy("foo@MyAdapter1") + compObj2 = communicator.stringToProxy("foo@MyAdapter2") + test(compObj1 != compObj2) + test(compObj1 < compObj2) + test(not (compObj2 < compObj1)) + + test(compObj1.ice_locatorCacheTimeout(20) == compObj1.ice_locatorCacheTimeout(20)) + test(compObj1.ice_locatorCacheTimeout(10) != compObj1.ice_locatorCacheTimeout(20)) + test(compObj1.ice_locatorCacheTimeout(10) < compObj1.ice_locatorCacheTimeout(20)) + test(not (compObj1.ice_locatorCacheTimeout(20) < compObj1.ice_locatorCacheTimeout(10))) + + test(compObj1.ice_invocationTimeout(20) == compObj1.ice_invocationTimeout(20)); + test(compObj1.ice_invocationTimeout(10) != compObj1.ice_invocationTimeout(20)); + test(compObj1.ice_invocationTimeout(10) < compObj1.ice_invocationTimeout(20)); + test(not (compObj1.ice_invocationTimeout(20) < compObj1.ice_invocationTimeout(10))); + + compObj1 = communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 1000") + compObj2 = communicator.stringToProxy("foo@MyAdapter1") + test(compObj1 != compObj2) + test(compObj1 < compObj2) + test(not (compObj2 < compObj1)) + + endpts1 = communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 10000").ice_getEndpoints() + endpts2 = communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 10001").ice_getEndpoints() + test(endpts1 != endpts2) + test(endpts1 < endpts2) + test(not (endpts2 < endpts1)) + test(endpts1 == communicator.stringToProxy("foo:tcp -h 127.0.0.1 -p 10000").ice_getEndpoints()) + + test(compObj1.ice_encodingVersion(Ice.Encoding_1_0) == compObj1.ice_encodingVersion(Ice.Encoding_1_0)) + test(compObj1.ice_encodingVersion(Ice.Encoding_1_0) != compObj1.ice_encodingVersion(Ice.Encoding_1_1)) + test(compObj.ice_encodingVersion(Ice.Encoding_1_0) < compObj.ice_encodingVersion(Ice.Encoding_1_1)) + test(not (compObj.ice_encodingVersion(Ice.Encoding_1_1) < compObj.ice_encodingVersion(Ice.Encoding_1_0))) + + # + # TODO: Ideally we should also test comparison of fixed proxies. + # + + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + cl = Test.MyClassPrx.checkedCast(base) + test(cl) + + derived = Test.MyDerivedClassPrx.checkedCast(cl) + test(derived) + test(cl == base) + test(derived == base) + test(cl == derived) + + loc = Ice.LocatorPrx.checkedCast(base) + test(loc == None) + + # + # Upcasting + # + cl2 = Test.MyClassPrx.checkedCast(derived) + obj = Ice.ObjectPrx.checkedCast(derived) + test(cl2) + test(obj) + test(cl2 == obj) + test(cl2 == derived) + + print("ok") + + sys.stdout.write("testing checked cast with context... ") + sys.stdout.flush() + tccp = Test.MyClassPrx.checkedCast(base) + c = tccp.getContext() + test(c == None or len(c) == 0) + + c = { } + c["one"] = "hello" + c["two"] = "world" + tccp = Test.MyClassPrx.checkedCast(base, c) + c2 = tccp.getContext() + test(c == c2) + print("ok") + + sys.stdout.write("testing encoding versioning... ") + sys.stdout.flush() + ref20 = "test -e 2.0:default -p 12010"; + cl20 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref20)); + try: + cl20.ice_ping(); + test(false); + except Ice.UnsupportedEncodingException: + # Server 2.0 endpoint doesn't support 1.1 version. + pass + + ref10 = "test -e 1.0:default -p 12010" + cl10 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref10)) + cl10.ice_ping() + cl10.ice_encodingVersion(Ice.Encoding_1_0).ice_ping() + cl.ice_encodingVersion(Ice.Encoding_1_0).ice_ping() + + # 1.3 isn't supported but since a 1.3 proxy supports 1.1, the + # call will use the 1.1 encoding + ref13 = "test -e 1.3:default -p 12010" + cl13 = Test.MyClassPrx.uncheckedCast(communicator.stringToProxy(ref13)) + cl13.ice_ping() + + print("ok") + + sys.stdout.write("testing opaque endpoints... ") + sys.stdout.flush() + + try: + # Invalid -x option + p = communicator.stringToProxy("id:opaque -t 99 -v abc -x abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Missing -t and -v + p = communicator.stringToProxy("id:opaque") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Repeated -t + p = communicator.stringToProxy("id:opaque -t 1 -t 1 -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Repeated -v + p = communicator.stringToProxy("id:opaque -t 1 -v abc -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Missing -t + p = communicator.stringToProxy("id:opaque -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Missing -v + p = communicator.stringToProxy("id:opaque -t 1") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Missing arg for -t + p = communicator.stringToProxy("id:opaque -t -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Missing arg for -v + p = communicator.stringToProxy("id:opaque -t 1 -v") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Not a number for -t + p = communicator.stringToProxy("id:opaque -t x -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # < 0 for -t + p = communicator.stringToProxy("id:opaque -t -1 -v abc") + test(False) + except Ice.EndpointParseException: + pass + + try: + # Invalid char for -v + p = communicator.stringToProxy("id:opaque -t 99 -v x?c") + test(False) + except Ice.EndpointParseException: + pass + + # Legal TCP endpoint expressed as opaque endpoint + p1 = communicator.stringToProxy("test -e 1.1:opaque -t 1 -e 1.0 -v CTEyNy4wLjAuMeouAAAQJwAAAA==") + pstr = communicator.proxyToString(p1) + test(pstr == "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000") + + # Opaque endpoint encoded with 1.1 encoding. + p2 = communicator.stringToProxy("test -e 1.1:opaque -e 1.1 -t 1 -v CTEyNy4wLjAuMeouAAAQJwAAAA==") + test(communicator.proxyToString(p2) == "test -t -e 1.1:tcp -h 127.0.0.1 -p 12010 -t 10000") + + if communicator.getProperties().getPropertyAsInt("Ice.IPv6") == 0: + # Working? + ssl = communicator.getProperties().getProperty("Ice.Default.Protocol") == "ssl" + tcp = communicator.getProperties().getProperty("Ice.Default.Protocol") == "tcp" + if tcp: + p1.ice_encodingVersion(Ice.Encoding_1_0).ice_ping() + + # Two legal TCP endpoints expressed as opaque endpoints + p1 = communicator.stringToProxy("test -e 1.0:opaque -t 1 -e 1.0 -v CTEyNy4wLjAuMeouAAAQJwAAAA==:opaque -t 1 -e 1.0 -v CTEyNy4wLjAuMusuAAAQJwAAAA==") + pstr = communicator.proxyToString(p1) + test(pstr == "test -t -e 1.0:tcp -h 127.0.0.1 -p 12010 -t 10000:tcp -h 127.0.0.2 -p 12011 -t 10000") + + # + # Test that an SSL endpoint and a nonsense endpoint get written + # back out as an opaque endpoint. + # + p1 = communicator.stringToProxy("test -e 1.0:opaque -t 2 -e 1.0 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -e 1.0 -v abch") + pstr = communicator.proxyToString(p1) + if ssl: + test(pstr == "test -t -e 1.0:ssl -h 127.0.0.1 -p 10001 -t infinite:opaque -t 99 -e 1.0 -v abch") + elif tcp: + test(pstr == "test -t -e 1.0:opaque -t 2 -e 1.0 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -e 1.0 -v abch") + + # + # Try to invoke on the SSL endpoint to verify that we get a + # NoEndpointException (or ConnectionRefusedException when + # running with SSL). + # + try: + p1.ice_encodingVersion(Ice.Encoding_1_0).ice_ping() + test(False) + except Ice.NoEndpointException: + test(not ssl) + except Ice.ConnectFailedException: + test(not tcp) + + # + # Test that the proxy with an SSL endpoint and a nonsense + # endpoint (which the server doesn't understand either) can be + # sent over the wire and returned by the server without losing + # the opaque endpoints. + # + p2 = derived.echo(p1) + pstr = communicator.proxyToString(p2) + if ssl: + test(pstr == "test -t -e 1.0:ssl -h 127.0.0.1 -p 10001 -t infinite:opaque -t 99 -e 1.0 -v abch") + elif tcp: + test(pstr == "test -t -e 1.0:opaque -t 2 -e 1.0 -v CTEyNy4wLjAuMREnAAD/////AA==:opaque -t 99 -e 1.0 -v abch") + + print("ok") + + return cl diff --git a/python/test/Ice/proxy/Client.py b/python/test/Ice/proxy/Client.py new file mode 100755 index 00000000000..442bd795711 --- /dev/null +++ b/python/test/Ice/proxy/Client.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + myClass = AllTests.allTests(communicator, False) + myClass.shutdown() + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/proxy/Collocated.py b/python/test/Ice/proxy/Collocated.py new file mode 100755 index 00000000000..a66580d803a --- /dev/null +++ b/python/test/Ice/proxy/Collocated.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test, TestI, AllTests + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TestI.MyDerivedClassI(), communicator.stringToIdentity("test")) + #adapter.activate() // Don't activate OA to ensure collocation is used. + + AllTests.allTests(communicator, True) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/proxy/Server.py b/python/test/Ice/proxy/Server.py new file mode 100755 index 00000000000..cf5e7289225 --- /dev/null +++ b/python/test/Ice/proxy/Server.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test, TestI + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TestI.MyDerivedClassI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/proxy/ServerAMD.py b/python/test/Ice/proxy/ServerAMD.py new file mode 100755 index 00000000000..f94496bbcb7 --- /dev/null +++ b/python/test/Ice/proxy/ServerAMD.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' TestAMD.ice") +import Test + +class MyDerivedClassI(Test.MyDerivedClass): + def __init__(self): + self.ctx = None + + def shutdown_async(self, cb, current=None): + current.adapter.getCommunicator().shutdown() + cb.ice_response() + + def getContext_async(self, cb, current): + return cb.ice_response(self.ctx) + + def echo_async(self, cb, obj, current): + return cb.ice_response(obj) + + def ice_isA(self, s, current): + self.ctx = current.ctx + return Test.MyDerivedClass.ice_isA(self, s, current) + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(MyDerivedClassI(), communicator.stringToIdentity("test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Connections", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/proxy/Test.ice b/python/test/Ice/proxy/Test.ice new file mode 100644 index 00000000000..7f3701e81e2 --- /dev/null +++ b/python/test/Ice/proxy/Test.ice @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +class MyClass +{ + void shutdown(); + + Ice::Context getContext(); +}; + +class MyDerivedClass extends MyClass +{ + Object* echo(Object* obj); +}; + +}; diff --git a/python/test/Ice/proxy/TestAMD.ice b/python/test/Ice/proxy/TestAMD.ice new file mode 100644 index 00000000000..f69fb3a10b6 --- /dev/null +++ b/python/test/Ice/proxy/TestAMD.ice @@ -0,0 +1,29 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Ice/Current.ice> + +module Test +{ + +["amd"] class MyClass +{ + void shutdown(); + + Ice::Context getContext(); +}; + +["amd"] class MyDerivedClass extends MyClass +{ + Object* echo(Object* obj); +}; + +}; diff --git a/python/test/Ice/proxy/TestI.py b/python/test/Ice/proxy/TestI.py new file mode 100644 index 00000000000..72464f6d2ca --- /dev/null +++ b/python/test/Ice/proxy/TestI.py @@ -0,0 +1,28 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test +import time + +class MyDerivedClassI(Test.MyDerivedClass): + def __init__(self): + self.ctx = None + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def getContext(self, current): + return self.ctx + + def echo(self, obj, current): + return obj + + def ice_isA(self, s, current): + self.ctx = current.ctx + return Test.MyDerivedClass.ice_isA(self, s, current) diff --git a/python/test/Ice/proxy/run.py b/python/test/Ice/proxy/run.py new file mode 100755 index 00000000000..767b20c0a2c --- /dev/null +++ b/python/test/Ice/proxy/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("tests with regular server.") +TestUtil.clientServerTest() +print("tests with AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") +print("tests with collocated server.") +TestUtil.collocatedTest(" --Ice.ThreadPool.Client.SizeMax=2 --Ice.ThreadPool.Client.SizeWarn=0") diff --git a/python/test/Ice/servantLocator/AllTests.py b/python/test/Ice/servantLocator/AllTests.py new file mode 100644 index 00000000000..debe76df441 --- /dev/null +++ b/python/test/Ice/servantLocator/AllTests.py @@ -0,0 +1,226 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import sys, Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def testExceptions(obj, collocated): + + try: + obj.requestFailedException() + test(False) + except Ice.ObjectNotExistException as ex: + test(ex.id == obj.ice_getIdentity()) + test(ex.facet == obj.ice_getFacet()) + test(ex.operation == "requestFailedException") + except: + test(False) + + try: + obj.unknownUserException() + test(False) + except Ice.UnknownUserException as ex: + test(ex.unknown == "reason") + except: + test(False) + + try: + obj.unknownLocalException() + test(False) + except Ice.UnknownLocalException as ex: + test(ex.unknown == "reason") + except: + test(False) + + try: + obj.unknownException() + test(False) + except Ice.UnknownException as ex: + test(ex.unknown == "reason") + pass + + try: + obj.userException() + test(False) + except Ice.UnknownUserException as ex: + test(ex.unknown.find("Test::TestIntfUserException") >= 0) + except Ice.OperationNotExistException: + pass + except AttributeError: + pass + except: + test(False) + + try: + obj.localException() + test(False) + except Ice.UnknownLocalException as ex: + test(not collocated) + test(ex.unknown.find("Ice.SocketException") >= 0 or ex.unknown.find("Ice::SocketException") >= 0) + except SocketException: + test(collocated) + except: + test(False) + + try: + obj.pythonException() + test(False) + except Ice.UnknownException as ex: + test(ex.unknown.find("RuntimeError: message") >= 0) + except Ice.OperationNotExistException: + pass + except AttributeError: + pass + except: + test(False) + + try: + obj.unknownExceptionWithServantException() + test(False) + except Ice.UnknownException as ex: + test(ex.unknown == "reason") + except: + test(False) + + try: + obj.impossibleException(False) + test(False) + except Ice.UnknownUserException: + # Operation doesn't throw, but locate() and finished() throw TestIntfUserException. + pass + except: + test(False) + + try: + obj.impossibleException(True) + test(False) + except Ice.UnknownUserException: + # Operation doesn't throw, but locate() and finished() throw TestIntfUserException. + pass + except: + test(False) + + try: + obj.intfUserException(False) + test(False) + except Test.TestImpossibleException: + # Operation doesn't throw, but locate() and finished() throw TestImpossibleException. + pass + except: + test(False) + + try: + obj.intfUserException(True) + test(False) + except Test.TestImpossibleException: + # Operation throws TestIntfUserException, but locate() and finished() throw TestImpossibleException. + pass + except: + test(False) + +def allTests(communicator, collocated): + sys.stdout.write("testing stringToProxy... ") + sys.stdout.flush() + base = communicator.stringToProxy("asm:default -p 12010") + test(base) + print("ok") + + sys.stdout.write("testing checked cast... ") + sys.stdout.flush() + obj = Test.TestIntfPrx.checkedCast(base) + test(obj) + test(obj == base) + print("ok") + + sys.stdout.write("testing ice_ids... ") + sys.stdout.flush() + try: + obj = communicator.stringToProxy("category/locate:default -p 12010") + obj.ice_ids() + test(False) + except Ice.UnknownUserException as ex: + test(ex.unknown == "Test::TestIntfUserException") + except: + test(False) + + try: + obj = communicator.stringToProxy("category/finished:default -p 12010") + obj.ice_ids() + test(False) + except Ice.UnknownUserException as ex: + test(ex.unknown == "Test::TestIntfUserException") + except: + test(False) + print("ok") + + sys.stdout.write("testing servant locator... ") + sys.stdout.flush() + base = communicator.stringToProxy("category/locate:default -p 12010") + obj = Test.TestIntfPrx.checkedCast(base) + try: + Test.TestIntfPrx.checkedCast(communicator.stringToProxy("category/unknown:default -p 12010")) + except Ice.ObjectNotExistException: + pass + print("ok") + + sys.stdout.write("testing default servant locator... ") + sys.stdout.flush() + base = communicator.stringToProxy("anothercat/locate:default -p 12010") + obj = Test.TestIntfPrx.checkedCast(base) + base = communicator.stringToProxy("locate:default -p 12010") + obj = Test.TestIntfPrx.checkedCast(base) + try: + Test.TestIntfPrx.checkedCast(communicator.stringToProxy("anothercat/unknown:default -p 12010")) + except Ice.ObjectNotExistException: + pass + try: + Test.TestIntfPrx.checkedCast(communicator.stringToProxy("unknown:default -p 12010")) + except Ice.ObjectNotExistException: + pass + print("ok") + + sys.stdout.write("testing locate exceptions... ") + sys.stdout.flush() + base = communicator.stringToProxy("category/locate:default -p 12010") + obj = Test.TestIntfPrx.checkedCast(base) + testExceptions(obj, collocated) + print("ok") + + sys.stdout.write("testing finished exceptions... ") + sys.stdout.flush() + base = communicator.stringToProxy("category/finished:default -p 12010") + obj = Test.TestIntfPrx.checkedCast(base) + testExceptions(obj, collocated) + print("ok") + + sys.stdout.write("testing servant locator removal... ") + sys.stdout.flush() + base = communicator.stringToProxy("test/activation:default -p 12010") + activation = Test.TestActivationPrx.checkedCast(base) + activation.activateServantLocator(False) + try: + obj.ice_ping() + test(False) + except Ice.ObjectNotExistException: + pass + print("ok") + + sys.stdout.write("testing servant locator addition... ") + sys.stdout.flush() + activation.activateServantLocator(True) + try: + obj.ice_ping() + except: + test(False) + print("ok") + + return obj diff --git a/python/test/Ice/servantLocator/Client.py b/python/test/Ice/servantLocator/Client.py new file mode 100755 index 00000000000..99ec03e78c3 --- /dev/null +++ b/python/test/Ice/servantLocator/Client.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +import Ice +Ice.loadSlice('Test.ice') +import Test, AllTests + +class TestClient(Ice.Application): + def run(self, args): + obj = AllTests.allTests(self.communicator(), False) + obj.shutdown() + return 0 + +app = TestClient() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/servantLocator/Collocated.py b/python/test/Ice/servantLocator/Collocated.py new file mode 100755 index 00000000000..ae176ff0320 --- /dev/null +++ b/python/test/Ice/servantLocator/Collocated.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI, AllTests, TestActivationI + +class TestServer(Ice.Application): + def run(self, args): + self.communicator().getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + self.communicator().getProperties().setProperty("Ice.Warn.Dispatch", "0") + + adapter = self.communicator().createObjectAdapter("TestAdapter") + #adapter.activate() // Don't activate OA to ensure collocation is used. + adapter.addServantLocator(TestI.ServantLocatorI("category"), "category") + adapter.addServantLocator(TestI.ServantLocatorI(""), "") + adapter.add(TestI.TestI(), self.communicator().stringToIdentity("asm")) + adapter.add(TestActivationI.TestActivationI(), self.communicator().stringToIdentity("test/activation")) + + AllTests.allTests(self.communicator(), False) + + adapter.deactivate() + adapter.waitForDeactivate() + return 0 + +app = TestServer() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/servantLocator/Server.py b/python/test/Ice/servantLocator/Server.py new file mode 100755 index 00000000000..567f1e1791b --- /dev/null +++ b/python/test/Ice/servantLocator/Server.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +Ice.loadSlice('Test.ice') +import Test, TestI, TestActivationI + +class TestServer(Ice.Application): + def run(self, args): + self.communicator().getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + self.communicator().getProperties().setProperty("Ice.Warn.Dispatch", "0") + + adapter = self.communicator().createObjectAdapter("TestAdapter") + adapter.addServantLocator(TestI.ServantLocatorI("category"), "category") + adapter.addServantLocator(TestI.ServantLocatorI(""), "") + adapter.add(TestI.TestI(), self.communicator().stringToIdentity("asm")) + adapter.add(TestActivationI.TestActivationI(), self.communicator().stringToIdentity("test/activation")) + + adapter.activate() + adapter.waitForDeactivate() + return 0 + +app = TestServer() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/servantLocator/ServerAMD.py b/python/test/Ice/servantLocator/ServerAMD.py new file mode 100755 index 00000000000..cd233e5c039 --- /dev/null +++ b/python/test/Ice/servantLocator/ServerAMD.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time + +import Ice +Ice.loadSlice('TestAMD.ice') +import Test, TestAMDI, TestActivationAMDI + +class TestServer(Ice.Application): + def run(self, args): + self.communicator().getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010") + self.communicator().getProperties().setProperty("Ice.Warn.Dispatch", "0") + + adapter = self.communicator().createObjectAdapter("TestAdapter") + adapter.addServantLocator(TestAMDI.ServantLocatorI("category"), "category") + adapter.addServantLocator(TestAMDI.ServantLocatorI(""), "") + adapter.add(TestAMDI.TestI(), self.communicator().stringToIdentity("asm")) + adapter.add(TestActivationAMDI.TestActivationAMDI(), self.communicator().stringToIdentity("test/activation")) + + adapter.activate() + adapter.waitForDeactivate() + return 0 + +app = TestServer() +sys.exit(app.main(sys.argv)) diff --git a/python/test/Ice/servantLocator/Test.ice b/python/test/Ice/servantLocator/Test.ice new file mode 100644 index 00000000000..52681603e36 --- /dev/null +++ b/python/test/Ice/servantLocator/Test.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception TestIntfUserException +{ +}; + +exception TestImpossibleException +{ +}; + +interface TestIntf +{ + void requestFailedException(); + void unknownUserException(); + void unknownLocalException(); + void unknownException(); + void localException(); + void userException(); + void pythonException(); + + void unknownExceptionWithServantException(); + + string impossibleException(bool throw) throws TestImpossibleException; + string intfUserException(bool throw) throws TestIntfUserException, TestImpossibleException; + + void asyncResponse() throws TestIntfUserException, TestImpossibleException; + void asyncException() throws TestIntfUserException, TestImpossibleException; + + void shutdown(); +}; + +interface TestActivation +{ + void activateServantLocator(bool activate); +}; + +local class Cookie +{ + ["cpp:const"] string message(); +}; + +}; diff --git a/python/test/Ice/servantLocator/TestAMD.ice b/python/test/Ice/servantLocator/TestAMD.ice new file mode 100644 index 00000000000..83512649026 --- /dev/null +++ b/python/test/Ice/servantLocator/TestAMD.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception TestIntfUserException +{ +}; + +exception TestImpossibleException +{ +}; + +["amd"] interface TestIntf +{ + void requestFailedException(); + void unknownUserException(); + void unknownLocalException(); + void unknownException(); + void localException(); + void userException(); + void pythonException(); + + void unknownExceptionWithServantException(); + + string impossibleException(bool throw) throws TestImpossibleException; + string intfUserException(bool throw) throws TestIntfUserException, TestImpossibleException; + + void asyncResponse() throws TestIntfUserException, TestImpossibleException; + void asyncException() throws TestIntfUserException, TestImpossibleException; + + void shutdown(); +}; + +interface TestActivation +{ + void activateServantLocator(bool activate); +}; + +local class Cookie +{ + ["cpp:const"] string message(); +}; + +}; diff --git a/python/test/Ice/servantLocator/TestAMDI.py b/python/test/Ice/servantLocator/TestAMDI.py new file mode 100644 index 00000000000..4ba7ca4f72f --- /dev/null +++ b/python/test/Ice/servantLocator/TestAMDI.py @@ -0,0 +1,157 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time +import Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestI(Test.TestIntf): + + def requestFailedException_async(self, cb, current=None): + cb.ice_response() + + def unknownUserException_async(self, cb, current=None): + cb.ice_response() + + def unknownLocalException_async(self, cb, current=None): + cb.ice_response() + + def unknownException_async(self, cb, current=None): + cb.ice_response() + + def localException_async(self, cb, current=None): + cb.ice_response() + + def userException_async(self, cb, current=None): + cb.ice_response() + + def pythonException_async(self, cb, current=None): + cb.ice_response() + + def unknownExceptionWithServantException_async(self, cb, current=None): + cb.ice_exception(Ice.ObjectNotExistException()) + + def impossibleException_async(self, cb, throw, current=None): + if throw: + cb.ice_exception(Test.TestImpossibleException()) + else: + # + # Return a value so we can be sure that the stream position + # is reset correctly if finished() throws. + # + cb.ice_response("Hello") + + def intfUserException_async(self, cb, throw, current=None): + if throw: + cb.ice_exception(Test.TestIntfUserException()) + else: + # + # Return a value so we can be sure that the stream position + # is reset correctly if finished() throws. + # + cb.ice_response("Hello") + + def asyncResponse_async(self, cb, current=None): + cb.ice_response() + raise Ice.ObjectNotExistException() + + def asyncException_async(self, cb, current=None): + cb.ice_exception(Test.TestIntfUserException()) + raise Ice.ObjectNotExistException() + + def shutdown_async(self, cb, current=None): + current.adapter.deactivate() + cb.ice_response() + +class CookieI(Test.Cookie): + def message(self): + return 'blahblah' + +class ServantLocatorI(Ice.ServantLocator): + def __init__(self, category): + self._deactivated = False + self._category = category + self._requestId = -1 + + def __del__(self): + test(self._deactivated) + + def locate(self, current): + test(not self._deactivated) + + test(current.id.category == self._category or self._category == "") + + if current.id.name == "unknown": + return None + + test(current.id.name == "locate" or current.id.name == "finished") + if current.id.name == "locate": + self.exception(current) + + # + # Ensure locate() is only called once per request. + # + test(self._requestId == -1) + self._requestId = current.requestId + + return (TestI(), CookieI()) + + def finished(self, current, servant, cookie): + test(not self._deactivated) + + # + # Ensure finished() is only called once per request. + # + test(self._requestId == current.requestId) + self._requestId = -1 + + test(current.id.category == self._category or self._category == "") + test(current.id.name == "locate" or current.id.name == "finished") + + if current.id.name == "finished": + self.exception(current) + + test(isinstance(cookie, Test.Cookie)) + test(cookie.message() == 'blahblah') + + def deactivate(self, category): + test(not self._deactivated) + + self._deactivated = True + + def exception(self, current): + if current.operation == "ice_ids": + raise Test.TestIntfUserException() + elif current.operation == "requestFailedException": + raise Ice.ObjectNotExistException() + elif current.operation == "unknownUserException": + raise Ice.UnknownUserException("reason") + elif current.operation == "unknownLocalException": + raise Ice.UnknownLocalException("reason") + elif current.operation == "unknownException": + raise Ice.UnknownException("reason") + elif current.operation == "userException": + raise Test.TestIntfUserException() + elif current.operation == "localException": + raise Ice.SocketException(0) + elif current.operation == "pythonException": + raise RuntimeError("message") + elif current.operation == "unknownExceptionWithServantException": + raise Ice.UnknownException("reason") + elif current.operation == "impossibleException": + raise Test.TestIntfUserException() # Yes, it really is meant to be TestIntfUserException. + elif current.operation == "intfUserException": + raise Test.TestImpossibleException() # Yes, it really is meant to be TestImpossibleException. + elif current.operation == "asyncResponse": + raise Test.TestImpossibleException() + elif current.operation == "asyncException": + raise Test.TestImpossibleException() diff --git a/python/test/Ice/servantLocator/TestActivationAMDI.py b/python/test/Ice/servantLocator/TestActivationAMDI.py new file mode 100644 index 00000000000..ade3027cb85 --- /dev/null +++ b/python/test/Ice/servantLocator/TestActivationAMDI.py @@ -0,0 +1,25 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time +import Ice, Test, TestAMDI + + +class TestActivationAMDI(Test.TestActivation): + + def activateServantLocator(self, activate, current=None): + if(activate): + current.adapter.addServantLocator(TestAMDI.ServantLocatorI(""), "") + current.adapter.addServantLocator(TestAMDI.ServantLocatorI("category"), "category") + else: + locator = current.adapter.removeServantLocator("") + locator.deactivate("") + locator = current.adapter.removeServantLocator("category") + locator.deactivate("category") + diff --git a/python/test/Ice/servantLocator/TestActivationI.py b/python/test/Ice/servantLocator/TestActivationI.py new file mode 100644 index 00000000000..026ec36af41 --- /dev/null +++ b/python/test/Ice/servantLocator/TestActivationI.py @@ -0,0 +1,25 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time +import Ice, Test, TestI + + +class TestActivationI(Test.TestActivation): + + def activateServantLocator(self, activate, current=None): + if activate: + current.adapter.addServantLocator(TestI.ServantLocatorI(""), "") + current.adapter.addServantLocator(TestI.ServantLocatorI("category"), "category") + else: + locator = current.adapter.removeServantLocator("") + locator.deactivate("") + locator = current.adapter.removeServantLocator("category") + locator.deactivate("category") + diff --git a/python/test/Ice/servantLocator/TestI.py b/python/test/Ice/servantLocator/TestI.py new file mode 100644 index 00000000000..19e724fd5d0 --- /dev/null +++ b/python/test/Ice/servantLocator/TestI.py @@ -0,0 +1,158 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time +import Ice, Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestI(Test.TestIntf): + + def requestFailedException(self, current=None): + pass + + def unknownUserException(self, current=None): + pass + + def unknownLocalException(self, current=None): + pass + + def unknownException(self, current=None): + pass + + def localException(self, current=None): + pass + + def userException(self, current=None): + pass + + def pythonException(self, current=None): + pass + + def unknownExceptionWithServantException(self, current=None): + raise Ice.ObjectNotExistException() + + def impossibleException(self, throw, current=None): + if throw: + raise Test.TestImpossibleException() + # + # Return a value so we can be sure that the stream position + # is reset correctly if finished() throws. + # + return "Hello" + + def intfUserException(self, throw, current=None): + if throw: + raise Test.TestIntfUserException() + # + # Return a value so we can be sure that the stream position + # is reset correctly if finished() throws. + # + return "Hello" + + def asyncResponse(self, current=None): + # + # Only relevant for AMD. + # + pass + + def asyncException(self, current=None): + # + # Only relevant for AMD. + # + pass + + def shutdown(self, current=None): + current.adapter.deactivate() + +class CookieI(Test.Cookie): + def message(self): + return 'blahblah' + +class ServantLocatorI(Ice.ServantLocator): + def __init__(self, category): + self._deactivated = False + self._category = category + self._requestId = -1 + + def __del__(self): + test(self._deactivated) + + def locate(self, current): + test(not self._deactivated) + + test(current.id.category == self._category or self._category == "") + + if current.id.name == "unknown": + return None + + test(current.id.name == "locate" or current.id.name == "finished") + if current.id.name == "locate": + self.exception(current) + + # + # Ensure locate() is only called once per request. + # + test(self._requestId == -1) + self._requestId = current.requestId + + return (TestI(), CookieI()) + + def finished(self, current, servant, cookie): + test(not self._deactivated) + + # + # Ensure finished() is only called once per request. + # + test(self._requestId == current.requestId) + self._requestId = -1 + + test(current.id.category == self._category or self._category == "") + test(current.id.name == "locate" or current.id.name == "finished") + + if current.id.name == "finished": + self.exception(current) + + test(isinstance(cookie, Test.Cookie)) + test(cookie.message() == 'blahblah') + + def deactivate(self, category): + test(not self._deactivated) + + self._deactivated = True + + def exception(self, current): + if current.operation == "ice_ids": + raise Test.TestIntfUserException() + elif current.operation == "requestFailedException": + raise Ice.ObjectNotExistException() + elif current.operation == "unknownUserException": + raise Ice.UnknownUserException("reason") + elif current.operation == "unknownLocalException": + raise Ice.UnknownLocalException("reason") + elif current.operation == "unknownException": + raise Ice.UnknownException("reason") + elif current.operation == "userException": + raise Test.TestIntfUserException() + elif current.operation == "localException": + raise Ice.SocketException(0) + elif current.operation == "pythonException": + raise RuntimeError("message") + elif current.operation == "unknownExceptionWithServantException": + raise Ice.UnknownException("reason") + elif current.operation == "impossibleException": + raise Test.TestIntfUserException() # Yes, it really is meant to be TestIntfUserException. + elif current.operation == "intfUserException": + raise Test.TestImpossibleException() # Yes, it really is meant to be TestImpossibleException. + elif current.operation == "asyncResponse": + raise Test.TestImpossibleException() + elif current.operation == "asyncException": + raise Test.TestImpossibleException() diff --git a/python/test/Ice/servantLocator/run.py b/python/test/Ice/servantLocator/run.py new file mode 100755 index 00000000000..767b20c0a2c --- /dev/null +++ b/python/test/Ice/servantLocator/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("tests with regular server.") +TestUtil.clientServerTest() +print("tests with AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") +print("tests with collocated server.") +TestUtil.collocatedTest(" --Ice.ThreadPool.Client.SizeMax=2 --Ice.ThreadPool.Client.SizeWarn=0") diff --git a/python/test/Ice/slicing/exceptions/AllTests.py b/python/test/Ice/slicing/exceptions/AllTests.py new file mode 100644 index 00000000000..07f860aeb1b --- /dev/null +++ b/python/test/Ice/slicing/exceptions/AllTests.py @@ -0,0 +1,589 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, threading, sys + +Ice.loadSlice('-I. --all ClientPrivate.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def response(self): + test(False) + + def exception_baseAsBase(self, exc): + try: + raise exc + except Test.Base as b: + test(b.b == "Base.b") + test(b.ice_name() =="Test::Base") + except: + test(False) + self.called() + + def exception_unknownDerivedAsBase(self, exc): + try: + raise exc + except Test.Base as b: + test(b.b == "UnknownDerived.b") + test(b.ice_name() =="Test::Base") + except: + test(False) + self.called() + + def exception_knownDerivedAsBase(self, exc): + try: + raise exc + except Test.KnownDerived as k: + test(k.b == "KnownDerived.b") + test(k.kd == "KnownDerived.kd") + test(k.ice_name() =="Test::KnownDerived") + except: + test(False) + self.called() + + def exception_knownDerivedAsKnownDerived(self, exc): + try: + raise exc + except Test.KnownDerived as k: + test(k.b == "KnownDerived.b") + test(k.kd == "KnownDerived.kd") + test(k.ice_name() =="Test::KnownDerived") + except: + test(False) + self.called() + + def exception_unknownIntermediateAsBase(self, exc): + try: + raise exc + except Test.Base as b: + test(b.b == "UnknownIntermediate.b") + test(b.ice_name() =="Test::Base") + except: + test(False) + self.called() + + def exception_knownIntermediateAsBase(self, exc): + try: + raise exc + except Test.KnownIntermediate as ki: + test(ki.b == "KnownIntermediate.b") + test(ki.ki == "KnownIntermediate.ki") + test(ki.ice_name() =="Test::KnownIntermediate") + except: + test(False) + self.called() + + def exception_knownMostDerivedAsBase(self, exc): + try: + raise exc + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() =="Test::KnownMostDerived") + except: + test(False) + self.called() + + def exception_knownIntermediateAsKnownIntermediate(self, exc): + try: + raise exc + except Test.KnownIntermediate as ki: + test(ki.b == "KnownIntermediate.b") + test(ki.ki == "KnownIntermediate.ki") + test(ki.ice_name() =="Test::KnownIntermediate") + except: + test(False) + self.called() + + def exception_knownMostDerivedAsKnownMostDerived(self, exc): + try: + raise exc + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() =="Test::KnownMostDerived") + except: + test(False) + self.called() + + def exception_knownMostDerivedAsKnownIntermediate(self, exc): + try: + raise exc + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() =="Test::KnownMostDerived") + except: + test(False) + self.called() + + def exception_unknownMostDerived1AsBase(self, exc): + try: + raise exc + except Test.KnownIntermediate as ki: + test(ki.b == "UnknownMostDerived1.b") + test(ki.ki == "UnknownMostDerived1.ki") + test(ki.ice_name() =="Test::KnownIntermediate") + except: + test(False) + self.called() + + def exception_unknownMostDerived1AsKnownIntermediate(self, exc): + try: + raise exc + except Test.KnownIntermediate as ki: + test(ki.b == "UnknownMostDerived1.b") + test(ki.ki == "UnknownMostDerived1.ki") + test(ki.ice_name() =="Test::KnownIntermediate") + except: + test(False) + self.called() + + def exception_unknownMostDerived2AsBase(self, exc): + try: + raise exc + except Test.Base as b: + test(b.b == "UnknownMostDerived2.b") + test(b.ice_name() =="Test::Base") + except: + test(False) + self.called() + +class RelayI(Test.Relay): + def knownPreservedAsBase(self, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + raise ex + + def knownPreservedAsKnownPreserved(self, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + raise ex + + def unknownPreservedAsBase(self, current=None): + ex = Test.Preserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.PreservedClass("bc", "pc") + ex.p2 = ex.p1 + raise ex + + def unknownPreservedAsKnownPreserved(self, current=None): + ex = Test.Preserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.PreservedClass("bc", "pc") + ex.p2 = ex.p1 + raise ex + +def allTests(communicator): + obj = communicator.stringToProxy("Test:default -p 12010") + t = Test.TestIntfPrx.checkedCast(obj) + + sys.stdout.write("base... ") + sys.stdout.flush() + try: + t.baseAsBase() + test(false) + except Test.Base as b: + test(b.b == "Base.b") + test(b.ice_name() == "Test::Base") + except: + test(False) + print("ok") + + sys.stdout.write("base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_baseAsBase(cb.response, cb.exception_baseAsBase) + cb.check() + print("ok") + + sys.stdout.write("slicing of unknown derived... ") + sys.stdout.flush() + try: + t.unknownDerivedAsBase() + test(false) + except Test.Base as b: + test(b.b == "UnknownDerived.b") + test(b.ice_name() == "Test::Base") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of unknown derived (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_unknownDerivedAsBase(cb.response, cb.exception_unknownDerivedAsBase) + cb.check() + print("ok") + + sys.stdout.write("non-slicing of known derived as base... ") + sys.stdout.flush() + try: + t.knownDerivedAsBase() + test(false) + except Test.KnownDerived as k: + test(k.b == "KnownDerived.b") + test(k.kd == "KnownDerived.kd") + test(k.ice_name() == "Test::KnownDerived") + except: + test(False) + print("ok") + + sys.stdout.write("non-slicing of known derived as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownDerivedAsBase(cb.response, cb.exception_knownDerivedAsBase) + cb.check() + print("ok") + + sys.stdout.write("non-slicing of known derived as derived... ") + sys.stdout.flush() + try: + t.knownDerivedAsKnownDerived() + test(false) + except Test.KnownDerived as k: + test(k.b == "KnownDerived.b") + test(k.kd == "KnownDerived.kd") + test(k.ice_name() == "Test::KnownDerived") + except: + test(False) + print("ok") + + sys.stdout.write("non-slicing of known derived as derived (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownDerivedAsKnownDerived(cb.response, cb.exception_knownDerivedAsKnownDerived) + cb.check() + print("ok") + + sys.stdout.write("slicing of unknown intermediate as base... ") + sys.stdout.flush() + try: + t.unknownIntermediateAsBase() + test(false) + except Test.Base as b: + test(b.b == "UnknownIntermediate.b") + test(b.ice_name() == "Test::Base") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of unknown intermediate as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_unknownIntermediateAsBase(cb.response, cb.exception_unknownIntermediateAsBase) + cb.check() + print("ok") + + sys.stdout.write("slicing of known intermediate as base... ") + sys.stdout.flush() + try: + t.knownIntermediateAsBase() + test(false) + except Test.KnownIntermediate as ki: + test(ki.b == "KnownIntermediate.b") + test(ki.ki == "KnownIntermediate.ki") + test(ki.ice_name() == "Test::KnownIntermediate") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of known intermediate as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownIntermediateAsBase(cb.response, cb.exception_knownIntermediateAsBase) + cb.check() + print("ok") + + sys.stdout.write("slicing of known most derived as base... ") + sys.stdout.flush() + try: + t.knownMostDerivedAsBase() + test(false) + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() == "Test::KnownMostDerived") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of known most derived as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownMostDerivedAsBase(cb.response, cb.exception_knownMostDerivedAsBase) + cb.check() + print("ok") + + sys.stdout.write("non-slicing of known intermediate as intermediate... ") + sys.stdout.flush() + try: + t.knownIntermediateAsKnownIntermediate() + test(false) + except Test.KnownIntermediate as ki: + test(ki.b == "KnownIntermediate.b") + test(ki.ki == "KnownIntermediate.ki") + test(ki.ice_name() == "Test::KnownIntermediate") + except: + test(False) + print("ok") + + sys.stdout.write("non-slicing of known intermediate as intermediate (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownIntermediateAsKnownIntermediate(cb.response, cb.exception_knownIntermediateAsKnownIntermediate) + cb.check() + print("ok") + + sys.stdout.write("non-slicing of known most derived exception as intermediate... ") + sys.stdout.flush() + try: + t.knownMostDerivedAsKnownIntermediate() + test(false) + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() == "Test::KnownMostDerived") + except: + test(False) + print("ok") + + sys.stdout.write("non-slicing of known most derived as intermediate (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownMostDerivedAsKnownIntermediate(cb.response, cb.exception_knownMostDerivedAsKnownIntermediate) + cb.check() + print("ok") + + sys.stdout.write("non-slicing of known most derived as most derived... ") + sys.stdout.flush() + try: + t.knownMostDerivedAsKnownMostDerived() + test(false) + except Test.KnownMostDerived as kmd: + test(kmd.b == "KnownMostDerived.b") + test(kmd.ki == "KnownMostDerived.ki") + test(kmd.kmd == "KnownMostDerived.kmd") + test(kmd.ice_name() == "Test::KnownMostDerived") + except: + test(False) + print("ok") + + sys.stdout.write("non-slicing of known most derived as most derived (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_knownMostDerivedAsKnownMostDerived(cb.response, cb.exception_knownMostDerivedAsKnownMostDerived) + cb.check() + print("ok") + + sys.stdout.write("slicing of unknown most derived, known intermediate as base... ") + sys.stdout.flush() + try: + t.unknownMostDerived1AsBase() + test(false) + except Test.KnownIntermediate as ki: + test(ki.b == "UnknownMostDerived1.b") + test(ki.ki == "UnknownMostDerived1.ki") + test(ki.ice_name() == "Test::KnownIntermediate") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of unknown most derived, known intermediate as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_unknownMostDerived1AsBase(cb.response, cb.exception_unknownMostDerived1AsBase) + cb.check() + print("ok") + + sys.stdout.write("slicing of unknown most derived, known intermediate as intermediate... ") + sys.stdout.flush() + try: + t.unknownMostDerived1AsKnownIntermediate() + test(false) + except Test.KnownIntermediate as ki: + test(ki.b == "UnknownMostDerived1.b") + test(ki.ki == "UnknownMostDerived1.ki") + test(ki.ice_name() == "Test::KnownIntermediate") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of unknown most derived, known intermediate as intermediate (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_unknownMostDerived1AsKnownIntermediate(cb.response, cb.exception_unknownMostDerived1AsKnownIntermediate) + cb.check() + print("ok") + + sys.stdout.write("slicing of unknown most derived, unknown intermediate as base... ") + sys.stdout.flush() + try: + t.unknownMostDerived2AsBase() + test(false) + except Test.Base as b: + test(b.b == "UnknownMostDerived2.b") + test(b.ice_name() == "Test::Base") + except: + test(False) + print("ok") + + sys.stdout.write("slicing of unknown most derived, unknown intermediate as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_unknownMostDerived2AsBase(cb.response, cb.exception_unknownMostDerived2AsBase) + cb.check() + print("ok") + + sys.stdout.write("unknown most derived in compact format... ") + sys.stdout.flush() + try: + t.unknownMostDerived2AsBaseCompact() + test(False) + except Test.Base: + # + # For the 1.0 encoding, the unknown exception is sliced to Base. + # + test(t.ice_getEncodingVersion() == Ice.Encoding_1_0) + except Ice.UnknownUserException: + # + # An UnkownUserException is raised for the compact format because the + # most-derived type is unknown and the exception cannot be sliced. + # + test(t.ice_getEncodingVersion() != Ice.Encoding_1_0) + except Ice.OperationNotExistException: + pass + except: + test(False) + print("ok") + + sys.stdout.write("preserved exceptions... ") + sys.stdout.flush() + adapter = communicator.createObjectAdapterWithEndpoints("Relay", "default") + relay = Test.RelayPrx.uncheckedCast(adapter.addWithUUID(RelayI())) + adapter.activate() + + try: + t.relayKnownPreservedAsBase(relay) + test(False) + except Test.KnownPreservedDerived as ex: + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + except Ice.OperationNotExistException: + pass + except: + test(False) + + try: + t.relayKnownPreservedAsKnownPreserved(relay) + test(False) + except Test.KnownPreservedDerived as ex: + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + except Ice.OperationNotExistException: + pass + except: + test(False) + + try: + t.relayUnknownPreservedAsBase(relay) + test(False) + except Test.Preserved2 as ex: + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + test(ex.p1.ice_id() == Test.PreservedClass.ice_staticId()) + pc = ex.p1 + test(isinstance(pc, Test.PreservedClass)) + test(pc.bc == "bc") + test(pc.pc == "pc") + test(ex.p2 == ex.p1) + except Test.KnownPreservedDerived as ex: + # + # For the 1.0 encoding, the unknown exception is sliced to KnownPreserved. + # + test(t.ice_getEncodingVersion() == Ice.Encoding_1_0) + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + except Ice.OperationNotExistException: + pass + except: + test(False) + + try: + t.relayUnknownPreservedAsKnownPreserved(relay) + test(False) + except Test.Preserved2 as ex: + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + test(ex.p1.ice_id() == Test.PreservedClass.ice_staticId()) + pc = ex.p1 + test(isinstance(pc, Test.PreservedClass)) + test(pc.bc == "bc") + test(pc.pc == "pc") + test(ex.p2 == ex.p1) + except Test.KnownPreservedDerived as ex: + # + # For the 1.0 encoding, the unknown exception is sliced to KnownPreserved. + # + test(t.ice_getEncodingVersion() == Ice.Encoding_1_0) + test(ex.b == "base") + test(ex.kp == "preserved") + test(ex.kpd == "derived") + except Ice.OperationNotExistException: + pass + except: + test(False) + + adapter.destroy() + print("ok") + + return t diff --git a/python/test/Ice/slicing/exceptions/Client.py b/python/test/Ice/slicing/exceptions/Client.py new file mode 100755 index 00000000000..2044a2d5b27 --- /dev/null +++ b/python/test/Ice/slicing/exceptions/Client.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice, AllTests + +def run(args, communicator): + Test = AllTests.allTests(communicator) + Test.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/exceptions/ClientPrivate.ice b/python/test/Ice/slicing/exceptions/ClientPrivate.ice new file mode 100644 index 00000000000..d7d016e5b65 --- /dev/null +++ b/python/test/Ice/slicing/exceptions/ClientPrivate.ice @@ -0,0 +1,32 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +class PreservedClass extends BaseClass +{ + string pc; +}; + +exception Preserved1 extends KnownPreservedDerived +{ + BaseClass p1; +}; + +exception Preserved2 extends Preserved1 +{ + BaseClass p2; +}; + +}; diff --git a/python/test/Ice/slicing/exceptions/Server.py b/python/test/Ice/slicing/exceptions/Server.py new file mode 100755 index 00000000000..833c79bfcec --- /dev/null +++ b/python/test/Ice/slicing/exceptions/Server.py @@ -0,0 +1,179 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback +import Ice +Ice.loadSlice('-I. --all ServerPrivate.ice') +import Test + +class TestI(Test.TestIntf): + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + + def baseAsBase(self, current=None): + b = Test.Base() + b.b = "Base.b" + raise b + + def unknownDerivedAsBase(self, current=None): + d = Test.UnknownDerived() + d.b = "UnknownDerived.b" + d.ud = "UnknownDerived.ud" + raise d + + def knownDerivedAsBase(self, current=None): + d = Test.KnownDerived() + d.b = "KnownDerived.b" + d.kd = "KnownDerived.kd" + raise d + + def knownDerivedAsKnownDerived(self, current=None): + d = Test.KnownDerived() + d.b = "KnownDerived.b" + d.kd = "KnownDerived.kd" + raise d + + def unknownIntermediateAsBase(self, current=None): + ui = Test.UnknownIntermediate() + ui.b = "UnknownIntermediate.b" + ui.ui = "UnknownIntermediate.ui" + raise ui + + def knownIntermediateAsBase(self, current=None): + ki = Test.KnownIntermediate() + ki.b = "KnownIntermediate.b" + ki.ki = "KnownIntermediate.ki" + raise ki + + def knownMostDerivedAsBase(self, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + raise kmd + + def knownIntermediateAsKnownIntermediate(self, current=None): + ki = Test.KnownIntermediate() + ki.b = "KnownIntermediate.b" + ki.ki = "KnownIntermediate.ki" + raise ki + + def knownMostDerivedAsKnownIntermediate(self, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + raise kmd + + def knownMostDerivedAsKnownMostDerived(self, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + raise kmd + + def unknownMostDerived1AsBase(self, current=None): + umd1 = Test.UnknownMostDerived1() + umd1.b = "UnknownMostDerived1.b" + umd1.ki = "UnknownMostDerived1.ki" + umd1.umd1 = "UnknownMostDerived1.umd1" + raise umd1 + + def unknownMostDerived1AsKnownIntermediate(self, current=None): + umd1 = Test.UnknownMostDerived1() + umd1.b = "UnknownMostDerived1.b" + umd1.ki = "UnknownMostDerived1.ki" + umd1.umd1 = "UnknownMostDerived1.umd1" + raise umd1 + + def unknownMostDerived2AsBase(self, current=None): + umd2 = Test.UnknownMostDerived2() + umd2.b = "UnknownMostDerived2.b" + umd2.ui = "UnknownMostDerived2.ui" + umd2.umd2 = "UnknownMostDerived2.umd2" + raise umd2 + + def unknownMostDerived2AsBaseCompact(self, current=None): + umd2 = Test.UnknownMostDerived2() + umd2.b = "UnknownMostDerived2.b" + umd2.ui = "UnknownMostDerived2.ui" + umd2.umd2 = "UnknownMostDerived2.umd2" + raise umd2 + + def knownPreservedAsBase(self, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + raise ex + + def knownPreservedAsKnownPreserved(self, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + raise ex + + def relayKnownPreservedAsBase(self, r, current=None): + r.knownPreservedAsBase() + + def relayKnownPreservedAsKnownPreserved(self, r, current=None): + r.knownPreservedAsKnownPreserved() + + def unknownPreservedAsBase(self, current=None): + ex = Test.SPreserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.SPreservedClass("bc", "spc") + ex.p2 = ex.p1 + raise ex + + def unknownPreservedAsKnownPreserved(self, current=None): + ex = Test.SPreserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.SPreservedClass("bc", "spc") + ex.p2 = ex.p1 + raise ex + + def relayUnknownPreservedAsBase(self, r, current=None): + r.unknownPreservedAsBase() + + def relayUnknownPreservedAsKnownPreserved(self, r, current=None): + r.unknownPreservedAsKnownPreserved() + +def run(args, communicator): + properties = communicator.getProperties() + properties.setProperty("Ice.Warn.Dispatch", "0") + properties.setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI() + adapter.add(object, communicator.stringToIdentity("Test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/exceptions/ServerAMD.py b/python/test/Ice/slicing/exceptions/ServerAMD.py new file mode 100755 index 00000000000..9a82839d7e9 --- /dev/null +++ b/python/test/Ice/slicing/exceptions/ServerAMD.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('-I. --all ServerPrivateAMD.ice') +import Test + +class TestI(Test.TestIntf): + def shutdown_async(self, cb, current=None): + current.adapter.getCommunicator().shutdown() + cb.ice_response() + + def baseAsBase_async(self, cb, current=None): + b = Test.Base() + b.b = "Base.b" + cb.ice_exception(b) + + def unknownDerivedAsBase_async(self, cb, current=None): + d = Test.UnknownDerived() + d.b = "UnknownDerived.b" + d.ud = "UnknownDerived.ud" + cb.ice_exception(d) + + def knownDerivedAsBase_async(self, cb, current=None): + d = Test.KnownDerived() + d.b = "KnownDerived.b" + d.kd = "KnownDerived.kd" + cb.ice_exception(d) + + def knownDerivedAsKnownDerived_async(self, cb, current=None): + d = Test.KnownDerived() + d.b = "KnownDerived.b" + d.kd = "KnownDerived.kd" + cb.ice_exception(d) + + def unknownIntermediateAsBase_async(self, cb, current=None): + ui = Test.UnknownIntermediate() + ui.b = "UnknownIntermediate.b" + ui.ui = "UnknownIntermediate.ui" + cb.ice_exception(ui) + + def knownIntermediateAsBase_async(self, cb, current=None): + ki = Test.KnownIntermediate() + ki.b = "KnownIntermediate.b" + ki.ki = "KnownIntermediate.ki" + cb.ice_exception(ki) + + def knownMostDerivedAsBase_async(self, cb, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + cb.ice_exception(kmd) + + def knownIntermediateAsKnownIntermediate_async(self, cb, current=None): + ki = Test.KnownIntermediate() + ki.b = "KnownIntermediate.b" + ki.ki = "KnownIntermediate.ki" + cb.ice_exception(ki) + + def knownMostDerivedAsKnownIntermediate_async(self, cb, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + cb.ice_exception(kmd) + + def knownMostDerivedAsKnownMostDerived_async(self, cb, current=None): + kmd = Test.KnownMostDerived() + kmd.b = "KnownMostDerived.b" + kmd.ki = "KnownMostDerived.ki" + kmd.kmd = "KnownMostDerived.kmd" + cb.ice_exception(kmd) + + def unknownMostDerived1AsBase_async(self, cb, current=None): + umd1 = Test.UnknownMostDerived1() + umd1.b = "UnknownMostDerived1.b" + umd1.ki = "UnknownMostDerived1.ki" + umd1.umd1 = "UnknownMostDerived1.umd1" + cb.ice_exception(umd1) + + def unknownMostDerived1AsKnownIntermediate_async(self, cb, current=None): + umd1 = Test.UnknownMostDerived1() + umd1.b = "UnknownMostDerived1.b" + umd1.ki = "UnknownMostDerived1.ki" + umd1.umd1 = "UnknownMostDerived1.umd1" + cb.ice_exception(umd1) + + def unknownMostDerived2AsBase_async(self, cb, current=None): + umd2 = Test.UnknownMostDerived2() + umd2.b = "UnknownMostDerived2.b" + umd2.ui = "UnknownMostDerived2.ui" + umd2.umd2 = "UnknownMostDerived2.umd2" + cb.ice_exception(umd2) + + def unknownMostDerived2AsBaseCompact_async(self, cb, current=None): + umd2 = Test.UnknownMostDerived2() + umd2.b = "UnknownMostDerived2.b" + umd2.ui = "UnknownMostDerived2.ui" + umd2.umd2 = "UnknownMostDerived2.umd2" + cb.ice_exception(umd2) + + def knownPreservedAsBase_async(self, cb, r, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + cb.ice_exception(ex) + + def knownPreservedAsKnownPreserved_async(self, cb, r, current=None): + ex = Test.KnownPreservedDerived() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + cb.ice_exception(ex) + + def relayKnownPreservedAsBase_async(self, cb, r, current=None): + try: + r.knownPreservedAsBase() + test(False) + except Ice.Exception as ex: + cb.ice_exception(ex) + + def relayKnownPreservedAsKnownPreserved_async(self, cb, r, current=None): + try: + r.knownPreservedAsKnownPreserved() + test(False) + except Ice.Exception as ex: + cb.ice_exception(ex) + + def unknownPreservedAsBase_async(self, cb, r, current=None): + ex = Test.SPreserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.SPreservedClass("bc", "spc") + ex.p2 = ex.p1 + cb.ice_exception(ex) + + def unknownPreservedAsKnownPreserved_async(self, cb, r, current=None): + ex = Test.SPreserved2() + ex.b = "base" + ex.kp = "preserved" + ex.kpd = "derived" + ex.p1 = Test.SPreservedClass("bc", "spc") + ex.p2 = ex.p1 + cb.ice_exception(ex) + + def relayUnknownPreservedAsBase_async(self, cb, r, current=None): + try: + r.unknownPreservedAsBase() + test(False) + except Ice.Exception as ex: + cb.ice_exception(ex) + + def relayUnknownPreservedAsKnownPreserved_async(self, cb, r, current=None): + try: + r.unknownPreservedAsKnownPreserved() + test(False) + except Ice.Exception as ex: + cb.ice_exception(ex) + +def run(args, communicator): + properties = communicator.getProperties() + properties.setProperty("Ice.Warn.Dispatch", "0") + properties.setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI() + adapter.add(object, communicator.stringToIdentity("Test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/exceptions/ServerPrivate.ice b/python/test/Ice/slicing/exceptions/ServerPrivate.ice new file mode 100644 index 00000000000..23284dcda1a --- /dev/null +++ b/python/test/Ice/slicing/exceptions/ServerPrivate.ice @@ -0,0 +1,52 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +exception UnknownDerived extends Base +{ + string ud; +}; + +exception UnknownIntermediate extends Base +{ + string ui; +}; + +exception UnknownMostDerived1 extends KnownIntermediate +{ + string umd1; +}; + +exception UnknownMostDerived2 extends UnknownIntermediate +{ + string umd2; +}; + +class SPreservedClass extends BaseClass +{ + string spc; +}; + +exception SPreserved1 extends KnownPreservedDerived +{ + BaseClass p1; +}; + +exception SPreserved2 extends SPreserved1 +{ + BaseClass p2; +}; + +}; diff --git a/python/test/Ice/slicing/exceptions/ServerPrivateAMD.ice b/python/test/Ice/slicing/exceptions/ServerPrivateAMD.ice new file mode 100644 index 00000000000..6f9a3259c09 --- /dev/null +++ b/python/test/Ice/slicing/exceptions/ServerPrivateAMD.ice @@ -0,0 +1,37 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <TestAMD.ice> + +module Test +{ + +exception UnknownDerived extends Base +{ + string ud; +}; + +exception UnknownIntermediate extends Base +{ + string ui; +}; + +exception UnknownMostDerived1 extends KnownIntermediate +{ + string umd1; +}; + +exception UnknownMostDerived2 extends UnknownIntermediate +{ + string umd2; +}; + +}; diff --git a/python/test/Ice/slicing/exceptions/Test.ice b/python/test/Ice/slicing/exceptions/Test.ice new file mode 100644 index 00000000000..e81c34580f6 --- /dev/null +++ b/python/test/Ice/slicing/exceptions/Test.ice @@ -0,0 +1,98 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception Base +{ + string b; +}; + +exception KnownDerived extends Base +{ + string kd; +}; + +exception KnownIntermediate extends Base +{ + string ki; +}; + +exception KnownMostDerived extends KnownIntermediate +{ + string kmd; +}; + +["preserve-slice"] +exception KnownPreserved extends Base +{ + string kp; +}; + +exception KnownPreservedDerived extends KnownPreserved +{ + string kpd; +}; + +["preserve-slice"] +class BaseClass +{ + string bc; +}; + +["format:sliced"] +interface Relay +{ + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; +}; + +["format:sliced"] +interface TestIntf +{ + void baseAsBase() throws Base; + void unknownDerivedAsBase() throws Base; + void knownDerivedAsBase() throws Base; + void knownDerivedAsKnownDerived() throws KnownDerived; + + void unknownIntermediateAsBase() throws Base; + void knownIntermediateAsBase() throws Base; + void knownMostDerivedAsBase() throws Base; + void knownIntermediateAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownMostDerived() throws KnownMostDerived; + + void unknownMostDerived1AsBase() throws Base; + void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate; + void unknownMostDerived2AsBase() throws Base; + + ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base; + + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayKnownPreservedAsBase(Relay* r) throws Base; + void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayUnknownPreservedAsBase(Relay* r) throws Base; + void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/slicing/exceptions/TestAMD.ice b/python/test/Ice/slicing/exceptions/TestAMD.ice new file mode 100644 index 00000000000..4a564781d4a --- /dev/null +++ b/python/test/Ice/slicing/exceptions/TestAMD.ice @@ -0,0 +1,98 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +exception Base +{ + string b; +}; + +exception KnownDerived extends Base +{ + string kd; +}; + +exception KnownIntermediate extends Base +{ + string ki; +}; + +exception KnownMostDerived extends KnownIntermediate +{ + string kmd; +}; + +["preserve-slice"] +exception KnownPreserved extends Base +{ + string kp; +}; + +exception KnownPreservedDerived extends KnownPreserved +{ + string kpd; +}; + +["preserve-slice"] +class BaseClass +{ + string bc; +}; + +["format:sliced"] +interface Relay +{ + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; +}; + +["amd", "format:sliced"] +interface TestIntf +{ + void baseAsBase() throws Base; + void unknownDerivedAsBase() throws Base; + void knownDerivedAsBase() throws Base; + void knownDerivedAsKnownDerived() throws KnownDerived; + + void unknownIntermediateAsBase() throws Base; + void knownIntermediateAsBase() throws Base; + void knownMostDerivedAsBase() throws Base; + void knownIntermediateAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownIntermediate() throws KnownIntermediate; + void knownMostDerivedAsKnownMostDerived() throws KnownMostDerived; + + void unknownMostDerived1AsBase() throws Base; + void unknownMostDerived1AsKnownIntermediate() throws KnownIntermediate; + void unknownMostDerived2AsBase() throws Base; + + ["format:compact"] void unknownMostDerived2AsBaseCompact() throws Base; + + void knownPreservedAsBase() throws Base; + void knownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayKnownPreservedAsBase(Relay* r) throws Base; + void relayKnownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void unknownPreservedAsBase() throws Base; + void unknownPreservedAsKnownPreserved() throws KnownPreserved; + + void relayUnknownPreservedAsBase(Relay* r) throws Base; + void relayUnknownPreservedAsKnownPreserved(Relay* r) throws KnownPreserved; + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/slicing/exceptions/run.py b/python/test/Ice/slicing/exceptions/run.py new file mode 100755 index 00000000000..95757ae246f --- /dev/null +++ b/python/test/Ice/slicing/exceptions/run.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../..", "../../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with sliced format.") +TestUtil.clientServerTest() + +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running test with sliced format and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") + +print("Running test with 1.0 encoding and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py", + additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") diff --git a/python/test/Ice/slicing/objects/AllTests.py b/python/test/Ice/slicing/objects/AllTests.py new file mode 100644 index 00000000000..c73a8df0b01 --- /dev/null +++ b/python/test/Ice/slicing/objects/AllTests.py @@ -0,0 +1,1833 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, gc, sys, threading + +Ice.loadSlice('-I. --all Forward.ice ClientPrivate.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def check(self): + self._cond.acquire() + try: + while not self._called: + self._cond.wait() + self._called = False + finally: + self._cond.release() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + +class Callback(CallbackBase): + def response_SBaseAsObject(self, o): + test(o) + test(o.ice_id() == "::Test::SBase") + sb = o + test(isinstance(sb, Test.SBase)) + test(sb.sb == "SBase.sb") + self.called() + + def response_SBaseAsSBase(self, sb): + test(sb.sb == "SBase.sb") + self.called() + + def response_SBSKnownDerivedAsSBase(self, sb): + sbskd = sb + test(isinstance(sbskd, Test.SBSKnownDerived)) + test(sbskd.sbskd == "SBSKnownDerived.sbskd") + self.called() + + def response_SBSKnownDerivedAsSBSKnownDerived(self, sbskd): + test(sbskd.sbskd == "SBSKnownDerived.sbskd") + self.called() + + def response_SBSUnknownDerivedAsSBase(self, sb): + test(sb.sb == "SBSUnknownDerived.sb") + self.called() + + def response_SBSUnknownDerivedAsSBaseCompact(self, sb): + test(False) + + def exception_SBSUnknownDerivedAsSBaseCompact(self, ex): + test(isinstance(ex, Ice.NoObjectFactoryException)) + self.called() + + def response_SUnknownAsObject10(self, o): + test(False) + + def exception_SUnknownAsObject10(self, exc): + test(exc.ice_name() == "Ice::NoObjectFactoryException") + self.called() + + def response_SUnknownAsObject11(self, o): + test(isinstance(o, Ice.UnknownSlicedObject)) + test(o.unknownTypeId == "::Test::SUnknown") + self.called() + + def exception_SUnknownAsObject11(self, exc): + test(False) + + def response_oneElementCycle(self, b): + test(b) + test(b.ice_id() == "::Test::B") + test(b.sb == "B1.sb") + test(b.pb == b) + self.called() + + def response_twoElementCycle(self, b1): + test(b1) + test(b1.ice_id() == "::Test::B") + test(b1.sb == "B1.sb") + + b2 = b1.pb + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "B2.sb") + test(b2.pb == b1) + self.called() + + def response_D1AsB(self, b1): + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb) + test(b1.pb != b1) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1) + test(d1.pd1 != b1) + test(b1.pb == d1.pd1) + + b2 = b1.pb + test(b2) + test(b2.pb == b1) + test(b2.sb == "D2.sb") + test(b2.ice_id() == "::Test::B") + self.called() + + def response_D1AsD1(self, d1): + test(d1) + test(d1.ice_id() == "::Test::D1") + test(d1.sb == "D1.sb") + test(d1.pb) + test(d1.pb != d1) + + b2 = d1.pb + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "D2.sb") + test(b2.pb == d1) + self.called() + + def response_D2AsB(self, b2): + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "D2.sb") + test(b2.pb) + test(b2.pb != b2) + + b1 = b2.pb + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb == b2) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1 == b2) + self.called() + + def response_paramTest1(self, b1, b2): + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb == b2) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1 == b2) + + test(b2) + test(b2.ice_id() == "::Test::B") # No factory, must be sliced + test(b2.sb == "D2.sb") + test(b2.pb == b1) + self.called() + + def response_returnTest1(self, r, p1, p2): + test(r == p1) + self.called() + + def response_returnTest2(self, r, p1, p2): + test(r == p1) + self.called() + + def response_returnTest3(self, b): + self.r = b + self.called() + + def response_paramTest3(self, ret, p1, p2): + test(p1) + test(p1.sb == "D2.sb (p1 1)") + test(p1.pb == None) + test(p1.ice_id() == "::Test::B") + + test(p2) + test(p2.sb == "D2.sb (p2 1)") + test(p2.pb == None) + test(p2.ice_id() == "::Test::B") + + test(ret) + test(ret.sb == "D1.sb (p2 2)") + test(ret.pb == None) + test(ret.ice_id() == "::Test::D1") + self.called() + + def response_paramTest4(self, ret, b): + test(b) + test(b.sb == "D4.sb (1)") + test(b.pb == None) + test(b.ice_id() == "::Test::B") + + test(ret) + test(ret.sb == "B.sb (2)") + test(ret.pb == None) + test(ret.ice_id() == "::Test::B") + self.called() + + def response_sequenceTest(self, ss): + self.r = ss + self.called() + + def response_dictionaryTest(self, r, bout): + self.r = r + self.bout = bout + self.called() + + def exception_throwBaseAsBase(self, ex): + test(ex.ice_name() == "Test::BaseException") + e = ex + test(isinstance(e, Test.BaseException)) + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb") + test(e.pb.pb == e.pb) + self.called() + + def exception_throwDerivedAsBase(self, ex): + test(ex.ice_name() == "Test::DerivedException") + e = ex + test(isinstance(e, Test.DerivedException)) + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb1") + test(e.pb.pb == e.pb) + test(e.sde == "sde1") + test(e.pd1) + test(e.pd1.sb == "sb2") + test(e.pd1.pb == e.pd1) + test(e.pd1.sd1 == "sd2") + test(e.pd1.pd1 == e.pd1) + self.called() + + def exception_throwDerivedAsDerived(self, ex): + test(ex.ice_name() == "Test::DerivedException") + e = ex + test(isinstance(e, Test.DerivedException)) + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb1") + test(e.pb.pb == e.pb) + test(e.sde == "sde1") + test(e.pd1) + test(e.pd1.sb == "sb2") + test(e.pd1.pb == e.pd1) + test(e.pd1.sd1 == "sd2") + test(e.pd1.pd1 == e.pd1) + self.called() + + def exception_throwUnknownDerivedAsBase(self, ex): + test(ex.ice_name() == "Test::BaseException") + e = ex + test(isinstance(e, Test.BaseException)) + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb d2") + test(e.pb.pb == e.pb) + self.called() + + def response_useForward(self, f): + test(f) + self.called() + + def response_preserved1(self, r): + test(r) + test(isinstance(r, Test.PDerived)) + test(r.pi == 3) + test(r.ps == "preserved") + test(r.pb == r) + self.called() + + def response_preserved2(self, r): + test(r) + test(not isinstance(r, Test.PCUnknown)) + test(r.pi == 3) + self.called() + + def response_preserved3(self, r): + # + # Encoding 1.0 + # + test(not isinstance(r, Test.PCDerived)) + test(r.pi == 3) + self.called() + + def response_preserved4(self, r): + # + # Encoding > 1.0 + # + test(isinstance(r, Test.PCDerived)) + test(r.pi == 3) + test(r.pbs[0] == r) + self.called() + + def response_preserved5(self, r): + test(isinstance(r, Test.PCDerived3)) + test(r.pi == 3) + for i in range(0, 300): + p2 = r.pbs[i] + test(isinstance(p2, Test.PCDerived2)) + test(p2.pi == i) + test(len(p2.pbs) == 1) + test(not p2.pbs[0]) + test(p2.pcd2 == i) + test(r.pcd2 == r.pi) + test(r.pcd3 == r.pbs[10]) + self.called() + + def response_compactPreserved1(self, r): + # + # Encoding 1.0 + # + test(not isinstance(r, Test.CompactPCDerived)) + test(r.pi == 3) + self.called() + + def response_compactPreserved2(self, r): + # + # Encoding > 1.0 + # + test(isinstance(r, Test.CompactPCDerived)) + test(r.pi == 3) + test(r.pbs[0] == r) + self.called() + + def response(self): + test(False) + + def exception(self, exc): + if(isinstance(exc, Ice.OperationNotExistException)): + self.called() + return + test(False) + +class PNodeI(Test.PNode): + counter = 0 + + def __init__(self): + PNodeI.counter = PNodeI.counter + 1 + + def __del__(self): + PNodeI.counter = PNodeI.counter - 1 + +class NodeFactoryI(Ice.ObjectFactory): + def create(self, id): + if id == Test.PNode.ice_staticId(): + return PNodeI() + return None + + def destroy(self): + pass + +class PreservedI(Test.Preserved): + counter = 0 + + def __init__(self): + PreservedI.counter = PreservedI.counter + 1 + + def __del__(self): + PreservedI.counter = PreservedI.counter - 1 + +class PreservedFactoryI(Ice.ObjectFactory): + def create(self, id): + if id == Test.Preserved.ice_staticId(): + return PreservedI() + return None + + def destroy(self): + pass + +def allTests(communicator): + obj = communicator.stringToProxy("Test:default -p 12010") + t = Test.TestIntfPrx.checkedCast(obj) + + sys.stdout.write("base as Object... ") + sys.stdout.flush() + o = None + try: + o = t.SBaseAsObject() + test(o) + test(o.ice_id() == "::Test::SBase") + except Ice.Exception: + test(False) + sb = o + test(isinstance(sb, Test.SBase)) + test(sb) + test(sb.sb == "SBase.sb") + print("ok") + + sys.stdout.write("base as Object (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_SBaseAsObject(cb.response_SBaseAsObject, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("base as base... ") + sys.stdout.flush() + try: + sb = t.SBaseAsSBase() + test(sb.sb == "SBase.sb") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("base as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_SBaseAsSBase(cb.response_SBaseAsSBase, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("base with known derived as base... ") + sys.stdout.flush() + try: + sb = t.SBSKnownDerivedAsSBase() + test(sb.sb == "SBSKnownDerived.sb") + except Ice.Exception: + test(False) + sbskd = sb + test(isinstance(sbskd, Test.SBSKnownDerived)) + test(sbskd) + test(sbskd.sbskd == "SBSKnownDerived.sbskd") + print("ok") + + sys.stdout.write("base with known derived as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_SBSKnownDerivedAsSBase(cb.response_SBSKnownDerivedAsSBase, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("base with known derived as known derived... ") + sys.stdout.flush() + try: + sbskd = t.SBSKnownDerivedAsSBSKnownDerived() + test(sbskd.sbskd == "SBSKnownDerived.sbskd") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("base with known derived as known derived (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_SBSKnownDerivedAsSBSKnownDerived(cb.response_SBSKnownDerivedAsSBSKnownDerived, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("base with unknown derived as base... ") + sys.stdout.flush() + try: + sb = t.SBSUnknownDerivedAsSBase() + test(sb.sb == "SBSUnknownDerived.sb") + except Ice.Exception: + test(False) + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + try: + # + # This test succeeds for the 1.0 encoding. + # + sb = t.SBSUnknownDerivedAsSBaseCompact() + test(sb.sb == "SBSUnknownDerived.sb") + except Ice.OperationNotExistException: + pass + except: + test(False) + else: + try: + # + # This test fails when using the compact format because the instance cannot + # be sliced to a known type. + # + sb = t.SBSUnknownDerivedAsSBaseCompact() + test(False) + except Ice.OperationNotExistException: + pass + except Ice.NoObjectFactoryException: + # Expected. + pass + except: + test(False) + print("ok") + + sys.stdout.write("base with unknown derived as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_SBSUnknownDerivedAsSBase(cb.response_SBSUnknownDerivedAsSBase, cb.exception) + cb.check() + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + # + # This test succeeds for the 1.0 encoding. + # + cb = Callback() + t.begin_SBSUnknownDerivedAsSBaseCompact(cb.response_SBSUnknownDerivedAsSBase, cb.exception) + cb.check() + else: + # + # This test fails when using the compact format because the instance cannot + # be sliced to a known type. + # + cb = Callback() + t.begin_SBSUnknownDerivedAsSBaseCompact(cb.response_SBSUnknownDerivedAsSBaseCompact, + cb.exception_SBSUnknownDerivedAsSBaseCompact) + cb.check() + print("ok") + + sys.stdout.write("unknown with Object as Object... ") + sys.stdout.flush() + try: + o = t.SUnknownAsObject() + test(t.ice_getEncodingVersion() != Ice.Encoding_1_0) + test(isinstance(o, Ice.UnknownSlicedObject)) + test(o.unknownTypeId == "::Test::SUnknown") + t.checkSUnknown(o) + except Ice.NoObjectFactoryException: + test(t.ice_getEncodingVersion() == Ice.Encoding_1_0) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("unknown with Object as Object (AMI)... ") + sys.stdout.flush() + try: + cb = Callback() + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + t.begin_SUnknownAsObject(cb.response_SUnknownAsObject10, cb.exception_SUnknownAsObject10) + else: + t.begin_SUnknownAsObject(cb.response_SUnknownAsObject11, cb.exception_SUnknownAsObject11) + cb.check() + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("one-element cycle... ") + sys.stdout.flush() + try: + b = t.oneElementCycle() + test(b) + test(b.ice_id() == "::Test::B") + test(b.sb == "B1.sb") + test(b.pb == b) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("one-element cycle (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_oneElementCycle(cb.response_oneElementCycle, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("two-element cycle... ") + sys.stdout.flush() + try: + b1 = t.twoElementCycle() + test(b1) + test(b1.ice_id() == "::Test::B") + test(b1.sb == "B1.sb") + + b2 = b1.pb + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "B2.sb") + test(b2.pb == b1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("two-element cycle (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_twoElementCycle(cb.response_twoElementCycle, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("known derived pointer slicing as base... ") + sys.stdout.flush() + try: + b1 = t.D1AsB() + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb) + test(b1.pb != b1) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1) + test(d1.pd1 != b1) + test(b1.pb == d1.pd1) + + b2 = b1.pb + test(b2) + test(b2.pb == b1) + test(b2.sb == "D2.sb") + test(b2.ice_id() == "::Test::B") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("known derived pointer slicing as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_D1AsB(cb.response_D1AsB, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("known derived pointer slicing as derived... ") + sys.stdout.flush() + try: + d1 = t.D1AsD1() + test(d1) + test(d1.ice_id() == "::Test::D1") + test(d1.sb == "D1.sb") + test(d1.pb) + test(d1.pb != d1) + + b2 = d1.pb + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "D2.sb") + test(b2.pb == d1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("known derived pointer slicing as derived (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_D1AsD1(cb.response_D1AsD1, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("unknown derived pointer slicing as base... ") + sys.stdout.flush() + try: + b2 = t.D2AsB() + test(b2) + test(b2.ice_id() == "::Test::B") + test(b2.sb == "D2.sb") + test(b2.pb) + test(b2.pb != b2) + + b1 = b2.pb + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb == b2) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1 == b2) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("unknown derived pointer slicing as base (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_D2AsB(cb.response_D2AsB, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("param ptr slicing with known first... ") + sys.stdout.flush() + try: + b1, b2 = t.paramTest1() + + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb == b2) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1 == b2) + + test(b2) + test(b2.ice_id() == "::Test::B") # No factory, must be sliced + test(b2.sb == "D2.sb") + test(b2.pb == b1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("param ptr slicing with known first (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_paramTest1(cb.response_paramTest1, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("param ptr slicing with unknown first... ") + sys.stdout.flush() + try: + b2, b1 = t.paramTest2() + + test(b1) + test(b1.ice_id() == "::Test::D1") + test(b1.sb == "D1.sb") + test(b1.pb == b2) + d1 = b1 + test(isinstance(d1, Test.D1)) + test(d1.sd1 == "D1.sd1") + test(d1.pd1 == b2) + + test(b2) + test(b2.ice_id() == "::Test::B") # No factory, must be sliced + test(b2.sb == "D2.sb") + test(b2.pb == b1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity with known first... ") + sys.stdout.flush() + try: + r, p1, p2 = t.returnTest1() + test(r == p1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity with known first (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_returnTest1(cb.response_returnTest1, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("return value identity with unknown first... ") + sys.stdout.flush() + try: + r, p1, p2 = t.returnTest2() + test(r == p1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity with unknown first (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_returnTest2(cb.response_returnTest2, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("return value identity for input params known first... ") + sys.stdout.flush() + try: + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d3 = Test.D3() + d3.pb = d1 + d3.sb = "D3.sb" + d3.sd3 = "D3.sd3" + d3.pd3 = d1 + d1.pb = d3 + d1.pd1 = d3 + + b1 = t.returnTest3(d1, d3) + + test(b1) + test(b1.sb == "D1.sb") + test(b1.ice_id() == "::Test::D1") + p1 = b1 + test(isinstance(p1, Test.D1)) + test(p1.sd1 == "D1.sd1") + test(p1.pd1 == b1.pb) + + b2 = b1.pb + test(b2) + test(b2.sb == "D3.sb") + test(b2.ice_id() == "::Test::B") # Sliced by server + test(b2.pb == b1) + p3 = b2 + test(not isinstance(p3, Test.D3)) + + test(b1 != d1) + test(b1 != d3) + test(b2 != d1) + test(b2 != d3) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity for input params known first (AMI)... ") + sys.stdout.flush() + try: + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d3 = Test.D3() + d3.pb = d1 + d3.sb = "D3.sb" + d3.sd3 = "D3.sd3" + d3.pd3 = d1 + d1.pb = d3 + d1.pd1 = d3 + + cb = Callback() + t.begin_returnTest3(d1, d3, cb.response_returnTest3, cb.exception) + cb.check() + b1 = cb.r + + test(b1) + test(b1.sb == "D1.sb") + test(b1.ice_id() == "::Test::D1") + p1 = b1 + test(isinstance(p1, Test.D1)) + test(p1.sd1 == "D1.sd1") + test(p1.pd1 == b1.pb) + + b2 = b1.pb + test(b2) + test(b2.sb == "D3.sb") + test(b2.ice_id() == "::Test::B") # Sliced by server + test(b2.pb == b1) + p3 = b2 + test(not isinstance(p3, Test.D3)) + + test(b1 != d1) + test(b1 != d3) + test(b2 != d1) + test(b2 != d3) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity for input params unknown first... ") + sys.stdout.flush() + try: + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d3 = Test.D3() + d3.pb = d1 + d3.sb = "D3.sb" + d3.sd3 = "D3.sd3" + d3.pd3 = d1 + d1.pb = d3 + d1.pd1 = d3 + + b1 = t.returnTest3(d3, d1) + + test(b1) + test(b1.sb == "D3.sb") + test(b1.ice_id() == "::Test::B") # Sliced by server + p1 = b1 + test(not isinstance(p1, Test.D3)) + + b2 = b1.pb + test(b2) + test(b2.sb == "D1.sb") + test(b2.ice_id() == "::Test::D1") + test(b2.pb == b1) + p3 = b2 + test(isinstance(p3, Test.D1)) + test(p3.sd1 == "D1.sd1") + test(p3.pd1 == b1) + + test(b1 != d1) + test(b1 != d3) + test(b2 != d1) + test(b2 != d3) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("return value identity for input params unknown first (AMI)... ") + sys.stdout.flush() + try: + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d3 = Test.D3() + d3.pb = d1 + d3.sb = "D3.sb" + d3.sd3 = "D3.sd3" + d3.pd3 = d1 + d1.pb = d3 + d1.pd1 = d3 + + cb = Callback() + t.begin_returnTest3(d3, d1, cb.response_returnTest3, cb.exception) + cb.check() + b1 = cb.r + + test(b1) + test(b1.sb == "D3.sb") + test(b1.ice_id() == "::Test::B") # Sliced by server + p1 = b1 + test(not isinstance(p1, Test.D3)) + + b2 = b1.pb + test(b2) + test(b2.sb == "D1.sb") + test(b2.ice_id() == "::Test::D1") + test(b2.pb == b1) + p3 = b2 + test(isinstance(p3, Test.D1)) + test(p3.sd1 == "D1.sd1") + test(p3.pd1 == b1) + + test(b1 != d1) + test(b1 != d3) + test(b2 != d1) + test(b2 != d3) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("remainder unmarshaling (3 instances)... ") + sys.stdout.flush() + try: + ret, p1, p2 = t.paramTest3() + + test(p1) + test(p1.sb == "D2.sb (p1 1)") + test(p1.pb == None) + test(p1.ice_id() == "::Test::B") + + test(p2) + test(p2.sb == "D2.sb (p2 1)") + test(p2.pb == None) + test(p2.ice_id() == "::Test::B") + + test(ret) + test(ret.sb == "D1.sb (p2 2)") + test(ret.pb == None) + test(ret.ice_id() == "::Test::D1") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("remainder unmarshaling (3 instances) (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_paramTest3(cb.response_paramTest3, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("remainder unmarshaling (4 instances)... ") + sys.stdout.flush() + try: + ret, b = t.paramTest4() + + test(b) + test(b.sb == "D4.sb (1)") + test(b.pb == None) + test(b.ice_id() == "::Test::B") + + test(ret) + test(ret.sb == "B.sb (2)") + test(ret.pb == None) + test(ret.ice_id() == "::Test::B") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("remainder unmarshaling (4 instances) (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_paramTest4(cb.response_paramTest4, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("param ptr slicing, instance marshaled in unknown derived as base... ") + sys.stdout.flush() + try: + b1 = Test.B() + b1.sb = "B.sb(1)" + b1.pb = b1 + + d3 = Test.D3() + d3.sb = "D3.sb" + d3.pb = d3 + d3.sd3 = "D3.sd3" + d3.pd3 = b1 + + b2 = Test.B() + b2.sb = "B.sb(2)" + b2.pb = b1 + + r = t.returnTest3(d3, b2) + + test(r) + test(r.ice_id() == "::Test::B") + test(r.sb == "D3.sb") + test(r.pb == r) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("param ptr slicing, instance marshaled in unknown derived as base (AMI)... ") + sys.stdout.flush() + try: + b1 = Test.B() + b1.sb = "B.sb(1)" + b1.pb = b1 + + d3 = Test.D3() + d3.sb = "D3.sb" + d3.pb = d3 + d3.sd3 = "D3.sd3" + d3.pd3 = b1 + + b2 = Test.B() + b2.sb = "B.sb(2)" + b2.pb = b1 + + cb = Callback() + t.begin_returnTest3(d3, b2, cb.response_returnTest3, cb.exception) + cb.check() + r = cb.r + + test(r) + test(r.ice_id() == "::Test::B") + test(r.sb == "D3.sb") + test(r.pb == r) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("param ptr slicing, instance marshaled in unknown derived as derived... ") + sys.stdout.flush() + try: + d11 = Test.D1() + d11.sb = "D1.sb(1)" + d11.pb = d11 + d11.sd1 = "D1.sd1(1)" + d11.pd1 = None + + d3 = Test.D3() + d3.sb = "D3.sb" + d3.pb = d3 + d3.sd3 = "D3.sd3" + d3.pd3 = d11 + + d12 = Test.D1() + d12.sb = "D1.sb(2)" + d12.pb = d12 + d12.sd1 = "D1.sd1(2)" + d12.pd1 = d11 + + r = t.returnTest3(d3, d12) + test(r) + test(r.ice_id() == "::Test::B") + test(r.sb == "D3.sb") + test(r.pb == r) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("param ptr slicing, instance marshaled in unknown derived as derived (AMI)... ") + sys.stdout.flush() + try: + d11 = Test.D1() + d11.sb = "D1.sb(1)" + d11.pb = d11 + d11.sd1 = "D1.sd1(1)" + d11.pd1 = None + + d3 = Test.D3() + d3.sb = "D3.sb" + d3.pb = d3 + d3.sd3 = "D3.sd3" + d3.pd3 = d11 + + d12 = Test.D1() + d12.sb = "D1.sb(2)" + d12.pb = d12 + d12.sd1 = "D1.sd1(2)" + d12.pd1 = d11 + + cb = Callback() + t.begin_returnTest3(d3, d12, cb.response_returnTest3, cb.exception) + cb.check() + r = cb.r + + test(r) + test(r.ice_id() == "::Test::B") + test(r.sb == "D3.sb") + test(r.pb == r) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("sequence slicing... ") + sys.stdout.flush() + try: + ss = Test.SS3() + ss1b = Test.B() + ss1b.sb = "B.sb" + ss1b.pb = ss1b + + ss1d1 = Test.D1() + ss1d1.sb = "D1.sb" + ss1d1.sd1 = "D1.sd1" + ss1d1.pb = ss1b + + ss1d3 = Test.D3() + ss1d3.sb = "D3.sb" + ss1d3.sd3 = "D3.sd3" + ss1d3.pb = ss1b + + ss2b = Test.B() + ss2b.sb = "B.sb" + ss2b.pb = ss1b + + ss2d1 = Test.D1() + ss2d1.sb = "D1.sb" + ss2d1.sd1 = "D1.sd1" + ss2d1.pb = ss2b + + ss2d3 = Test.D3() + ss2d3.sb = "D3.sb" + ss2d3.sd3 = "D3.sd3" + ss2d3.pb = ss2b + + ss1d1.pd1 = ss2b + ss1d3.pd3 = ss2d1 + + ss2d1.pd1 = ss1d3 + ss2d3.pd3 = ss1d1 + + ss1 = Test.SS1() + ss1.s = (ss1b, ss1d1, ss1d3) + + ss2 = Test.SS2() + ss2.s = (ss2b, ss2d1, ss2d3) + + ss = t.sequenceTest(ss1, ss2) + + test(ss.c1) + ss1b = ss.c1.s[0] + ss1d1 = ss.c1.s[1] + test(ss.c2) + ss1d3 = ss.c1.s[2] + + test(ss.c2) + ss2b = ss.c2.s[0] + ss2d1 = ss.c2.s[1] + ss2d3 = ss.c2.s[2] + + test(ss1b.pb == ss1b) + test(ss1d1.pb == ss1b) + test(ss1d3.pb == ss1b) + + test(ss2b.pb == ss1b) + test(ss2d1.pb == ss2b) + test(ss2d3.pb == ss2b) + + test(ss1b.ice_id() == "::Test::B") + test(ss1d1.ice_id() == "::Test::D1") + test(ss1d3.ice_id() == "::Test::B") + + test(ss2b.ice_id() == "::Test::B") + test(ss2d1.ice_id() == "::Test::D1") + test(ss2d3.ice_id() == "::Test::B") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("sequence slicing (AMI)... ") + sys.stdout.flush() + try: + ss = Test.SS3() + ss1b = Test.B() + ss1b.sb = "B.sb" + ss1b.pb = ss1b + + ss1d1 = Test.D1() + ss1d1.sb = "D1.sb" + ss1d1.sd1 = "D1.sd1" + ss1d1.pb = ss1b + + ss1d3 = Test.D3() + ss1d3.sb = "D3.sb" + ss1d3.sd3 = "D3.sd3" + ss1d3.pb = ss1b + + ss2b = Test.B() + ss2b.sb = "B.sb" + ss2b.pb = ss1b + + ss2d1 = Test.D1() + ss2d1.sb = "D1.sb" + ss2d1.sd1 = "D1.sd1" + ss2d1.pb = ss2b + + ss2d3 = Test.D3() + ss2d3.sb = "D3.sb" + ss2d3.sd3 = "D3.sd3" + ss2d3.pb = ss2b + + ss1d1.pd1 = ss2b + ss1d3.pd3 = ss2d1 + + ss2d1.pd1 = ss1d3 + ss2d3.pd3 = ss1d1 + + ss1 = Test.SS1() + ss1.s = (ss1b, ss1d1, ss1d3) + + ss2 = Test.SS2() + ss2.s = (ss2b, ss2d1, ss2d3) + + cb = Callback() + t.begin_sequenceTest(ss1, ss2, cb.response_sequenceTest, cb.exception) + cb.check() + ss = cb.r + + test(ss.c1) + ss1b = ss.c1.s[0] + ss1d1 = ss.c1.s[1] + test(ss.c2) + ss1d3 = ss.c1.s[2] + + test(ss.c2) + ss2b = ss.c2.s[0] + ss2d1 = ss.c2.s[1] + ss2d3 = ss.c2.s[2] + + test(ss1b.pb == ss1b) + test(ss1d1.pb == ss1b) + test(ss1d3.pb == ss1b) + + test(ss2b.pb == ss1b) + test(ss2d1.pb == ss2b) + test(ss2d3.pb == ss2b) + + test(ss1b.ice_id() == "::Test::B") + test(ss1d1.ice_id() == "::Test::D1") + test(ss1d3.ice_id() == "::Test::B") + + test(ss2b.ice_id() == "::Test::B") + test(ss2d1.ice_id() == "::Test::D1") + test(ss2d3.ice_id() == "::Test::B") + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("dictionary slicing... ") + sys.stdout.flush() + try: + bin = {} + for i in range(0, 10): + d1 = Test.D1() + s = "D1." + str(i) + d1.sb = s + d1.pb = d1 + d1.sd1 = s + d1.pd1 = None + bin[i] = d1 + + r, bout = t.dictionaryTest(bin) + + test(len(bout) == 10) + for i in range(0, 10): + b = bout[i * 10] + test(b) + s = "D1." + str(i) + test(b.sb == s) + test(b.pb) + test(b.pb != b) + test(b.pb.sb == s) + test(b.pb.pb == b.pb) + + test(len(r) == 10) + for i in range(0, 10): + b = r[i * 20] + test(b) + s = "D1." + str(i * 20) + test(b.sb == s) + if i == 0: + test(b.pb == None) + else: + test(b.pb == r[(i - 1) * 20]) + d1 = b + test(isinstance(d1, Test.D1)) + test(d1.sd1 == s) + test(d1.pd1 == d1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("dictionary slicing (AMI)... ") + sys.stdout.flush() + try: + bin = {} + for i in range(0, 10): + d1 = Test.D1() + s = "D1." + str(i) + d1.sb = s + d1.pb = d1 + d1.sd1 = s + d1.pd1 = None + bin[i] = d1 + + cb = Callback() + t.begin_dictionaryTest(bin, cb.response_dictionaryTest, cb.exception) + cb.check() + bout = cb.bout + r = cb.r + + test(len(bout) == 10) + for i in range(0, 10): + b = bout[i * 10] + test(b) + s = "D1." + str(i) + test(b.sb == s) + test(b.pb) + test(b.pb != b) + test(b.pb.sb == s) + test(b.pb.pb == b.pb) + + test(len(r) == 10) + for i in range(0, 10): + b = r[i * 20] + test(b) + s = "D1." + str(i * 20) + test(b.sb == s) + if i == 0: + test(b.pb == None) + else: + test(b.pb == r[(i - 1) * 20]) + d1 = b + test(isinstance(d1, Test.D1)) + test(d1.sd1 == s) + test(d1.pd1 == d1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("base exception thrown as base exception... ") + sys.stdout.flush() + try: + t.throwBaseAsBase() + test(False) + except Test.BaseException as e: + test(e.ice_name() == "Test::BaseException") + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb") + test(e.pb.pb == e.pb) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("base exception thrown as base exception (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_throwBaseAsBase(cb.response, cb.exception_throwBaseAsBase) + cb.check() + print("ok") + + sys.stdout.write("derived exception thrown as base exception... ") + sys.stdout.flush() + try: + t.throwDerivedAsBase() + test(False) + except Test.DerivedException as e: + test(e.ice_name() == "Test::DerivedException") + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb1") + test(e.pb.pb == e.pb) + test(e.sde == "sde1") + test(e.pd1) + test(e.pd1.sb == "sb2") + test(e.pd1.pb == e.pd1) + test(e.pd1.sd1 == "sd2") + test(e.pd1.pd1 == e.pd1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("derived exception thrown as base exception (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_throwDerivedAsBase(cb.response, cb.exception_throwDerivedAsBase) + cb.check() + print("ok") + + sys.stdout.write("derived exception thrown as derived exception... ") + sys.stdout.flush() + try: + t.throwDerivedAsDerived() + test(False) + except Test.DerivedException as e: + test(e.ice_name() == "Test::DerivedException") + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb1") + test(e.pb.pb == e.pb) + test(e.sde == "sde1") + test(e.pd1) + test(e.pd1.sb == "sb2") + test(e.pd1.pb == e.pd1) + test(e.pd1.sd1 == "sd2") + test(e.pd1.pd1 == e.pd1) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("derived exception thrown as derived exception (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_throwDerivedAsDerived(cb.response, cb.exception_throwDerivedAsDerived) + cb.check() + print("ok") + + sys.stdout.write("unknown derived exception thrown as base exception... ") + sys.stdout.flush() + try: + t.throwUnknownDerivedAsBase() + test(False) + except Test.BaseException as e: + test(e.ice_name() == "Test::BaseException") + test(e.sbe == "sbe") + test(e.pb) + test(e.pb.sb == "sb d2") + test(e.pb.pb == e.pb) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("unknown derived exception thrown as base exception (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_throwUnknownDerivedAsBase(cb.response, cb.exception_throwUnknownDerivedAsBase) + cb.check() + print("ok") + + sys.stdout.write("forward-declared class... ") + sys.stdout.flush() + try: + f = t.useForward() + test(f) + except Ice.Exception: + test(False) + print("ok") + + sys.stdout.write("forward-declared class (AMI)... ") + sys.stdout.flush() + cb = Callback() + t.begin_useForward(cb.response_useForward, cb.exception) + cb.check() + print("ok") + + sys.stdout.write("preserved classes... ") + sys.stdout.flush() + + try: + # + # Server knows the most-derived class PDerived. + # + pd = Test.PDerived() + pd.pi = 3 + pd.ps = "preserved" + pd.pb = pd + + r = t.exchangePBase(pd) + test(isinstance(r, Test.PDerived)) + test(r.pi == 3) + test(r.ps == "preserved") + test(r.pb == r) + + # + # Server only knows the base (non-preserved) type, so the object is sliced. + # + pu = Test.PCUnknown() + pu.pi = 3 + pu.pu = "preserved" + + r = t.exchangePBase(pu) + test(not isinstance(r, Test.PCUnknown)) + test(r.pi == 3) + + # + # Server only knows the intermediate type Preserved. The object will be sliced to + # Preserved for the 1.0 encoding; otherwise it should be returned intact. + # + pcd = Test.PCDerived() + pcd.pi = 3 + pcd.pbs = [ pcd ] + + r = t.exchangePBase(pcd) + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + test(not isinstance(r, Test.PCDerived)) + test(r.pi == 3) + else: + test(isinstance(r, Test.PCDerived)) + test(r.pi == 3) + test(r.pbs[0] == r) + + # + # Server only knows the intermediate type CompactPDerived. The object will be sliced to + # CompactPDerived for the 1.0 encoding; otherwise it should be returned intact. + # + pcd = Test.CompactPCDerived() + pcd.pi = 3 + pcd.pbs = [ pcd ] + + r = t.exchangePBase(pcd) + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + test(not isinstance(r, Test.CompactPCDerived)) + test(r.pi == 3) + else: + test(isinstance(r, Test.CompactPCDerived)) + test(r.pi == 3) + test(r.pbs[0] == r) + + # + # Send an object that will have multiple preserved slices in the server. + # The object will be sliced to Preserved for the 1.0 encoding. + # + pcd = Test.PCDerived3() + pcd.pi = 3 + # + # Sending more than 254 objects exercises the encoding for object ids. + # + pcd.pbs = [] + for i in range(0, 300): + p2 = Test.PCDerived2() + p2.pi = i + p2.pbs = [ None ] # Nil reference. This slice should not have an indirection table. + p2.pcd2 = i + pcd.pbs.append(p2) + pcd.pcd2 = pcd.pi + pcd.pcd3 = pcd.pbs[10] + + r = t.exchangePBase(pcd) + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + test(not isinstance(r, Test.PCDerived3)) + test(isinstance(r, Test.Preserved)) + test(r.pi == 3) + else: + test(isinstance(r, Test.PCDerived3)) + test(r.pi == 3) + for i in range(0, 300): + p2 = r.pbs[i] + test(isinstance(p2, Test.PCDerived2)) + test(p2.pi == i) + test(len(p2.pbs) == 1) + test(not p2.pbs[0]) + test(p2.pcd2 == i) + test(r.pcd2 == r.pi) + test(r.pcd3 == r.pbs[10]) + + # + # Obtain an object with preserved slices and send it back to the server. + # The preserved slices should be excluded for the 1.0 encoding, otherwise + # they should be included. + # + p = t.PBSUnknownAsPreserved() + t.checkPBSUnknown(p) + if t.ice_getEncodingVersion() != Ice.Encoding_1_0: + t.ice_encodingVersion(Ice.Encoding_1_0).checkPBSUnknown(p) + except Ice.OperationNotExistException: + pass + + print("ok") + + sys.stdout.write("preserved classes (AMI)... ") + sys.stdout.flush() + + # + # Server knows the most-derived class PDerived. + # + pd = Test.PDerived() + pd.pi = 3 + pd.ps = "preserved" + pd.pb = pd + + cb = Callback() + t.begin_exchangePBase(pd, cb.response_preserved1, cb.exception) + cb.check() + + # + # Server only knows the base (non-preserved) type, so the object is sliced. + # + pu = Test.PCUnknown() + pu.pi = 3 + pu.pu = "preserved" + + cb = Callback() + t.begin_exchangePBase(pu, cb.response_preserved2, cb.exception) + cb.check() + + # + # Server only knows the intermediate type Preserved. The object will be sliced to + # Preserved for the 1.0 encoding; otherwise it should be returned intact. + # + pcd = Test.PCDerived() + pcd.pi = 3 + pcd.pbs = [ pcd ] + + cb = Callback() + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + t.begin_exchangePBase(pcd, cb.response_preserved3, cb.exception) + else: + t.begin_exchangePBase(pcd, cb.response_preserved4, cb.exception) + cb.check() + + # + # Server only knows the intermediate type CompactPDerived. The object will be sliced to + # CompactPDerived for the 1.0 encoding; otherwise it should be returned intact. + # + pcd = Test.CompactPCDerived() + pcd.pi = 3 + pcd.pbs = [ pcd ] + + cb = Callback() + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + t.begin_exchangePBase(pcd, cb.response_compactPreserved1, cb.exception) + else: + t.begin_exchangePBase(pcd, cb.response_compactPreserved2, cb.exception) + cb.check() + + # + # Send an object that will have multiple preserved slices in the server. + # The object will be sliced to Preserved for the 1.0 encoding. + # + pcd = Test.PCDerived3() + pcd.pi = 3 + # + # Sending more than 254 objects exercises the encoding for object ids. + # + pcd.pbs = [] + for i in range(0, 300): + p2 = Test.PCDerived2() + p2.pi = i + p2.pbs = [ None ] # Nil reference. This slice should not have an indirection table. + p2.pcd2 = i + pcd.pbs.append(p2) + pcd.pcd2 = pcd.pi + pcd.pcd3 = pcd.pbs[10] + + cb = Callback() + if t.ice_getEncodingVersion() == Ice.Encoding_1_0: + t.begin_exchangePBase(pcd, cb.response_preserved3, cb.exception) + else: + t.begin_exchangePBase(pcd, cb.response_preserved5, cb.exception) + cb.check() + + print("ok") + + sys.stdout.write("garbage collection of preserved classes... ") + sys.stdout.flush() + try: + # + # Register a factory in order to substitute our own subclass of + # UCNode. This provides an easy way to determine how many + # unmarshaled instances currently exist. + # + communicator.addObjectFactory(NodeFactoryI(), Test.PNode.ice_staticId()) + + # + # Relay a graph through the server. This test uses a preserved class + # with a class member. + # + c = Test.PNode() + c.next = Test.PNode() + c.next.next = Test.PNode() + c.next.next.next = c # Create a cyclic graph. + + test(PNodeI.counter == 0) + n = t.exchangePNode(c) + test(PNodeI.counter == 3) + test(n.next != None) + test(n.next != n.next.next) + test(n.next.next != n.next.next.next) + test(n.next.next.next == n) + n = None # Release reference. + if sys.version_info[0] == 3 and sys.version_info[1] >= 4: + # + # In Python 3.4, objects with a __del__ method can still be collected. + # + gc.collect() + test(PNodeI.counter == 0) + else: + # + # The PNodeI class declares a __del__ method, which means the Python + # garbage collector will NOT collect a cycle of PNodeI objects. + # + gc.collect() # No effect. + test(PNodeI.counter == 3) + # + # The uncollectable objects are stored in gc.garbage. We have to + # manually break the cycle and then remove the objects from the + # gc.garbage list. + # + test(len(gc.garbage) > 0) + for o in gc.garbage: + if isinstance(o, PNodeI): + o.next = None + o = None # Remove last reference. + del gc.garbage[:] + test(PNodeI.counter == 0) + + # + # Obtain a preserved object from the server where the most-derived + # type is unknown. The preserved slice refers to a graph of PNode + # objects. + # + test(PNodeI.counter == 0) + p = t.PBSUnknownAsPreservedWithGraph() + test(p) + test(PNodeI.counter == 3) + t.checkPBSUnknownWithGraph(p) + p = None # Release reference. + if sys.version_info[0] == 3 and sys.version_info[1] >= 4: + # + # In Python 3.4, objects with a __del__ method can still be collected. + # + gc.collect() + test(PNodeI.counter == 0) + else: + # + # The PNodeI class declares a __del__ method, which means the Python + # garbage collector will NOT collect a cycle of PNodeI objects. + # + gc.collect() # No effect. + test(PNodeI.counter == 3) + # + # The uncollectable objects are stored in gc.garbage. We have to + # manually break the cycle and then remove the objects from the + # gc.garbage list. + # + test(len(gc.garbage) > 0) + for o in gc.garbage: + if isinstance(o, PNodeI): + o.next = None + o = None # Remove last reference. + del gc.garbage[:] + test(PNodeI.counter == 0) + + # + # Register a factory in order to substitute our own subclass of + # Preserved. This provides an easy way to determine how many + # unmarshaled instances currently exist. + # + communicator.addObjectFactory(PreservedFactoryI(), Test.Preserved.ice_staticId()) + + # + # Obtain a preserved object from the server where the most-derived + # type is unknown. A data member in the preserved slice refers to the + # outer object, so the chain of references looks like this: + # + # outer->slicedData->outer + # + test(PreservedI.counter == 0) + p = t.PBSUnknown2AsPreservedWithGraph() + test(p != None) + test(PreservedI.counter == 1) + t.checkPBSUnknown2WithGraph(p) + p._ice_slicedData = None # Break the cycle. + p = None # Release reference. + test(PreservedI.counter == 0) + + # + # Throw a preserved exception where the most-derived type is unknown. + # The preserved exception slice contains a class data member. This + # object is also preserved, and its most-derived type is also unknown. + # The preserved slice of the object contains a class data member that + # refers to itself. + # + # The chain of references looks like this: + # + # ex->slicedData->obj->slicedData->obj + # + try: + test(PreservedI.counter == 0) + + try: + t.throwPreservedException() + except Test.PreservedException as ex: + # + # The class instance is only retained when the encoding is > 1.0. + # + if t.ice_getEncodingVersion() != Ice.Encoding_1_0: + test(PreservedI.counter == 1) + gc.collect() # No effect. + test(PreservedI.counter == 1) + ex._ice_slicedData = None # Break the cycle. + + # + # Exception has gone out of scope. + # + if t.ice_getEncodingVersion() != Ice.Encoding_1_0: + gc.collect() + if sys.version_info[0] == 3 and sys.version_info[1] >= 4: + # + # In Python 3.4, objects with a __del__ method can still be collected. + # + test(len(gc.garbage) == 0) + else: + test(len(gc.garbage) > 0) + for o in gc.garbage: + if isinstance(o, PreservedI): + o._ice_slicedData = None + o = None # Remove last reference. + del gc.garbage[:] + test(PreservedI.counter == 0) + except Ice.Exception: + test(False) + except Ice.OperationNotExistException: + pass + + print("ok") + + return t diff --git a/python/test/Ice/slicing/objects/Client.py b/python/test/Ice/slicing/objects/Client.py new file mode 100755 index 00000000000..2044a2d5b27 --- /dev/null +++ b/python/test/Ice/slicing/objects/Client.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice, AllTests + +def run(args, communicator): + Test = AllTests.allTests(communicator) + Test.shutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/objects/ClientPrivate.ice b/python/test/Ice/slicing/objects/ClientPrivate.ice new file mode 100644 index 00000000000..3880bd583ab --- /dev/null +++ b/python/test/Ice/slicing/objects/ClientPrivate.ice @@ -0,0 +1,49 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +class D3 extends B +{ + string sd3; + B pd3; +}; + +["preserve-slice"] +class PCUnknown extends PBase +{ + string pu; +}; + +class PCDerived extends PDerived +{ + PBaseSeq pbs; +}; + +class PCDerived2 extends PCDerived +{ + int pcd2; +}; + +class PCDerived3 extends PCDerived2 +{ + Object pcd3; +}; + +class CompactPCDerived(57) extends CompactPDerived +{ + PBaseSeq pbs; +}; + +}; diff --git a/python/test/Ice/slicing/objects/Forward.ice b/python/test/Ice/slicing/objects/Forward.ice new file mode 100644 index 00000000000..89486e226cc --- /dev/null +++ b/python/test/Ice/slicing/objects/Forward.ice @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class Forward; + +class Hidden +{ + Forward f; +}; + +class Forward +{ + Hidden h; +}; + +}; diff --git a/python/test/Ice/slicing/objects/Server.py b/python/test/Ice/slicing/objects/Server.py new file mode 100755 index 00000000000..e5b7465d7af --- /dev/null +++ b/python/test/Ice/slicing/objects/Server.py @@ -0,0 +1,390 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('-I. --all ServerPrivate.ice Forward.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestI(Test.TestIntf): + def SBaseAsObject(self, current=None): + sb = Test.SBase() + sb.sb = "SBase.sb" + return sb + + def SBaseAsSBase(self, current=None): + sb = Test.SBase() + sb.sb = "SBase.sb" + return sb + + def SBSKnownDerivedAsSBase(self, current=None): + sbskd = Test.SBSKnownDerived() + sbskd.sb = "SBSKnownDerived.sb" + sbskd.sbskd = "SBSKnownDerived.sbskd" + return sbskd + + def SBSKnownDerivedAsSBSKnownDerived(self, current=None): + sbskd = Test.SBSKnownDerived() + sbskd.sb = "SBSKnownDerived.sb" + sbskd.sbskd = "SBSKnownDerived.sbskd" + return sbskd + + def SBSUnknownDerivedAsSBase(self, current=None): + sbsud = Test.SBSUnknownDerived() + sbsud.sb = "SBSUnknownDerived.sb" + sbsud.sbsud = "SBSUnknownDerived.sbsud" + return sbsud + + def SBSUnknownDerivedAsSBaseCompact(self, current=None): + sbsud = Test.SBSUnknownDerived() + sbsud.sb = "SBSUnknownDerived.sb" + sbsud.sbsud = "SBSUnknownDerived.sbsud" + return sbsud + + def SUnknownAsObject(self, current=None): + su = Test.SUnknown() + su.su = "SUnknown.su" + return su + + def checkSUnknown(self, obj, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(obj, Test.SUnknown)) + else: + test(isinstance(obj, Test.SUnknown)) + test(obj.su == "SUnknown.su") + + def oneElementCycle(self, current=None): + b = Test.B() + b.sb = "B1.sb" + b.pb = b + return b + + def twoElementCycle(self, current=None): + b1 = Test.B() + b1.sb = "B1.sb" + b2 = Test.B() + b2.sb = "B2.sb" + b2.pb = b1 + b1.pb = b2 + return b1 + + def D1AsB(self, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + return d1 + + def D1AsD1(self, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + return d1 + + def D2AsB(self, current=None): + d2 = Test.D2() + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d1 = Test.D1() + d1.pb = d2 + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d1.pd1 = d2 + d2.pb = d1 + d2.pd2 = d1 + return d2 + + def paramTest1(self, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + return (d1, d2) + + def paramTest2(self, current=None): + c = Ice.Current() + p1, p2 = self.paramTest1(c) + return (p2, p1) + + def paramTest3(self, current=None): + d2 = Test.D2() + d2.sb = "D2.sb (p1 1)" + d2.pb = None + d2.sd2 = "D2.sd2 (p1 1)" + + d1 = Test.D1() + d1.sb = "D1.sb (p1 2)" + d1.pb = None + d1.sd1 = "D1.sd2 (p1 2)" + d1.pd1 = None + d2.pd2 = d1 + + d4 = Test.D2() + d4.sb = "D2.sb (p2 1)" + d4.pb = None + d4.sd2 = "D2.sd2 (p2 1)" + + d3 = Test.D1() + d3.sb = "D1.sb (p2 2)" + d3.pb = None + d3.sd1 = "D1.sd2 (p2 2)" + d3.pd1 = None + d4.pd2 = d3 + + return (d3, d2, d4) + + def paramTest4(self, current=None): + d4 = Test.D4() + d4.sb = "D4.sb (1)" + d4.pb = None + d4.p1 = Test.B() + d4.p1.sb = "B.sb (1)" + d4.p1.pb = None + d4.p2 = Test.B() + d4.p2.sb = "B.sb (2)" + d4.p2.pb = None + return (d4.p2, d4) + + def returnTest1(self, current=None): + c = Ice.Current() + p1, p2 = self.paramTest1(c) + return (p1, p1, p2) + + def returnTest2(self, current=None): + c = Ice.Current() + p2, p1 = self.paramTest1(c) + return (p1, p1, p2) + + def returnTest3(self, p1, p2, current=None): + return p1 + + def sequenceTest(self, p1, p2, current=None): + ss = Test.SS3() + ss.c1 = p1 + ss.c2 = p2 + return ss + + def dictionaryTest(self, bin, current=None): + bout = {} + for i in range(0, 10): + b = bin[i] + d2 = Test.D2() + d2.sb = b.sb + d2.pb = b.pb + d2.sd2 = "D2" + d2.pd2 = d2 + bout[i * 10] = d2 + + r = {} + for i in range(0, 10): + s = "D1." + str(i * 20) + d1 = Test.D1() + d1.sb = s + if i == 0: + d1.pb = None + else: + d1.pb = r[(i - 1) * 20] + d1.sd1 = s + d1.pd1 = d1 + r[i * 20] = d1 + + return (r, bout) + + def exchangePBase(self, pb, current=None): + return pb + + def PBSUnknownAsPreserved(self, current=None): + r = Test.PSUnknown() + r.pi = 5 + r.ps = "preserved" + r.psu = "unknown" + r.graph = None + return r + + def checkPBSUnknown(self, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.psu == "unknown") + test(not p.graph) + + def PBSUnknownAsPreservedWithGraph_async(self, cb, current=None): + r = Test.PSUnknown() + r.pi = 5 + r.ps = "preserved" + r.psu = "unknown" + r.graph = Test.PNode() + r.graph.next = Test.PNode() + r.graph.next.next = Test.PNode() + r.graph.next.next.next = r.graph + cb.ice_response(r) + r.graph.next.next.next = None # Break the cycle. + + def checkPBSUnknownWithGraph(self, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.psu == "unknown") + test(p.graph != p.graph.next) + test(p.graph.next != p.graph.next.next) + test(p.graph.next.next.next == p.graph) + p.graph.next.next.next = None # Break the cycle. + + def PBSUnknown2AsPreservedWithGraph_async(self, cb, current=None): + r = Test.PSUnknown2() + r.pi = 5 + r.ps = "preserved" + r.pb = r + cb.ice_response(r) + r.pb = None # Break the cycle. + + def checkPBSUnknown2WithGraph(self, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown2)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown2)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.pb == p) + p.pb = None # Break the cycle. + + def exchangePNode(self, pn, current=None): + return pn + + def throwBaseAsBase(self, current=None): + be = Test.BaseException() + be.sbe = "sbe" + be.pb = Test.B() + be.pb.sb = "sb" + be.pb.pb = be.pb + raise be + + def throwDerivedAsBase(self, current=None): + de = Test.DerivedException() + de.sbe = "sbe" + de.pb = Test.B() + de.pb.sb = "sb1" + de.pb.pb = de.pb + de.sde = "sde1" + de.pd1 = Test.D1() + de.pd1.sb = "sb2" + de.pd1.pb = de.pd1 + de.pd1.sd1 = "sd2" + de.pd1.pd1 = de.pd1 + raise de + + def throwDerivedAsDerived(self, current=None): + de = Test.DerivedException() + de.sbe = "sbe" + de.pb = Test.B() + de.pb.sb = "sb1" + de.pb.pb = de.pb + de.sde = "sde1" + de.pd1 = Test.D1() + de.pd1.sb = "sb2" + de.pd1.pb = de.pd1 + de.pd1.sd1 = "sd2" + de.pd1.pd1 = de.pd1 + raise de + + def throwUnknownDerivedAsBase(self, current=None): + d2 = Test.D2() + d2.sb = "sb d2" + d2.pb = d2 + d2.sd2 = "sd2 d2" + d2.pd2 = d2 + + ude = Test.UnknownDerivedException() + ude.sbe = "sbe" + ude.pb = d2 + ude.sude = "sude" + ude.pd2 = d2 + raise ude + + def throwPreservedException_async(self, cb, current=None): + ue = Test.PSUnknownException() + ue.p = Test.PSUnknown2() + ue.p.pi = 5 + ue.p.ps = "preserved" + ue.p.pb = ue.p + cb.ice_exception(ue) + ue.p.pb = None # Break the cycle. + + def useForward(self, current=None): + f = Test.Forward() + f.h = Test.Hidden() + f.h.f = f + return f + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +def run(args, communicator): + properties = communicator.getProperties() + properties.setProperty("Ice.Warn.Dispatch", "0") + properties.setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI() + adapter.add(object, communicator.stringToIdentity("Test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/objects/ServerAMD.py b/python/test/Ice/slicing/objects/ServerAMD.py new file mode 100755 index 00000000000..9020ff30a5f --- /dev/null +++ b/python/test/Ice/slicing/objects/ServerAMD.py @@ -0,0 +1,419 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +Ice.loadSlice('-I. --all ServerPrivateAMD.ice Forward.ice') +import Test + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class TestI(Test.TestIntf): + def SBaseAsObject_async(self, cb, current=None): + sb = Test.SBase() + sb.sb = "SBase.sb" + cb.ice_response(sb) + + def SBaseAsSBase_async(self, cb, current=None): + sb = Test.SBase() + sb.sb = "SBase.sb" + cb.ice_response(sb) + + def SBSKnownDerivedAsSBase_async(self, cb, current=None): + sbskd = Test.SBSKnownDerived() + sbskd.sb = "SBSKnownDerived.sb" + sbskd.sbskd = "SBSKnownDerived.sbskd" + cb.ice_response(sbskd) + + def SBSKnownDerivedAsSBSKnownDerived_async(self, cb, current=None): + sbskd = Test.SBSKnownDerived() + sbskd.sb = "SBSKnownDerived.sb" + sbskd.sbskd = "SBSKnownDerived.sbskd" + cb.ice_response(sbskd) + + def SBSUnknownDerivedAsSBase_async(self, cb, current=None): + sbsud = Test.SBSUnknownDerived() + sbsud.sb = "SBSUnknownDerived.sb" + sbsud.sbsud = "SBSUnknownDerived.sbsud" + cb.ice_response(sbsud) + + def SBSUnknownDerivedAsSBaseCompact_async(self, cb, current=None): + sbsud = Test.SBSUnknownDerived() + sbsud.sb = "SBSUnknownDerived.sb" + sbsud.sbsud = "SBSUnknownDerived.sbsud" + cb.ice_response(sbsud) + + def SUnknownAsObject_async(self, cb, current=None): + su = Test.SUnknown() + su.su = "SUnknown.su" + cb.ice_response(su) + + def checkSUnknown_async(self, cb, obj, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(obj, Test.SUnknown)) + else: + test(isinstance(obj, Test.SUnknown)) + test(obj.su == "SUnknown.su") + cb.ice_response() + + def oneElementCycle_async(self, cb, current=None): + b = Test.B() + b.sb = "B1.sb" + b.pb = b + cb.ice_response(b) + + def twoElementCycle_async(self, cb, current=None): + b1 = Test.B() + b1.sb = "B1.sb" + b2 = Test.B() + b2.sb = "B2.sb" + b2.pb = b1 + b1.pb = b2 + cb.ice_response(b1) + + def D1AsB_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d1) + + def D1AsD1_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d1) + + def D2AsB_async(self, cb, current=None): + d2 = Test.D2() + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d1 = Test.D1() + d1.pb = d2 + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d1.pd1 = d2 + d2.pb = d1 + d2.pd2 = d1 + cb.ice_response(d2) + + def paramTest1_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d1, d2) + + def paramTest2_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d2, d1) + + def paramTest3_async(self, cb, current=None): + d2 = Test.D2() + d2.sb = "D2.sb (p1 1)" + d2.pb = None + d2.sd2 = "D2.sd2 (p1 1)" + + d1 = Test.D1() + d1.sb = "D1.sb (p1 2)" + d1.pb = None + d1.sd1 = "D1.sd2 (p1 2)" + d1.pd1 = None + d2.pd2 = d1 + + d4 = Test.D2() + d4.sb = "D2.sb (p2 1)" + d4.pb = None + d4.sd2 = "D2.sd2 (p2 1)" + + d3 = Test.D1() + d3.sb = "D1.sb (p2 2)" + d3.pb = None + d3.sd1 = "D1.sd2 (p2 2)" + d3.pd1 = None + d4.pd2 = d3 + + cb.ice_response(d3, d2, d4) + + def paramTest4_async(self, cb, current=None): + d4 = Test.D4() + d4.sb = "D4.sb (1)" + d4.pb = None + d4.p1 = Test.B() + d4.p1.sb = "B.sb (1)" + d4.p1.pb = None + d4.p2 = Test.B() + d4.p2.sb = "B.sb (2)" + d4.p2.pb = None + cb.ice_response(d4.p2, d4) + + def returnTest1_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d2, d2, d1) + + def returnTest2_async(self, cb, current=None): + d1 = Test.D1() + d1.sb = "D1.sb" + d1.sd1 = "D1.sd1" + d2 = Test.D2() + d2.pb = d1 + d2.sb = "D2.sb" + d2.sd2 = "D2.sd2" + d2.pd2 = d1 + d1.pb = d2 + d1.pd1 = d2 + cb.ice_response(d1, d1, d2) + + def returnTest3_async(self, cb, p1, p2, current=None): + cb.ice_response(p1) + + def sequenceTest_async(self, cb, p1, p2, current=None): + ss = Test.SS3() + ss.c1 = p1 + ss.c2 = p2 + cb.ice_response(ss) + + def dictionaryTest_async(self, cb, bin, current=None): + bout = {} + for i in range(0, 10): + b = bin[i] + d2 = Test.D2() + d2.sb = b.sb + d2.pb = b.pb + d2.sd2 = "D2" + d2.pd2 = d2 + bout[i * 10] = d2 + + r = {} + for i in range(0, 10): + s = "D1." + str(i * 20) + d1 = Test.D1() + d1.sb = s + if i == 0: + d1.pb = None + else: + d1.pb = r[(i - 1) * 20] + d1.sd1 = s + d1.pd1 = d1 + r[i * 20] = d1 + + cb.ice_response(r, bout) + + def exchangePBase_async(self, cb, pb, current=None): + cb.ice_response(pb) + + def PBSUnknownAsPreserved_async(self, cb, current=None): + r = Test.PSUnknown() + r.pi = 5 + r.ps = "preserved" + r.psu = "unknown" + r.graph = None + cb.ice_response(r) + + def checkPBSUnknown_async(self, cb, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.psu == "unknown") + test(not p.graph) + cb.ice_response() + + def PBSUnknownAsPreservedWithGraph_async(self, cb, current=None): + r = Test.PSUnknown() + r.pi = 5 + r.ps = "preserved" + r.psu = "unknown" + r.graph = Test.PNode() + r.graph.next = Test.PNode() + r.graph.next.next = Test.PNode() + r.graph.next.next.next = r.graph + cb.ice_response(r) + r.graph.next.next.next = None # Break the cycle. + + def checkPBSUnknownWithGraph_async(self, cb, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.psu == "unknown") + test(p.graph != p.graph.next) + test(p.graph.next != p.graph.next.next) + test(p.graph.next.next.next == p.graph) + p.graph.next.next.next = None # Break the cycle. + cb.ice_response() + + def PBSUnknown2AsPreservedWithGraph_async(self, cb, current=None): + r = Test.PSUnknown2() + r.pi = 5 + r.ps = "preserved" + r.pb = r + cb.ice_response(r) + r.pb = None # Break the cycle. + + def checkPBSUnknown2WithGraph_async(self, cb, p, current=None): + if current.encoding == Ice.Encoding_1_0: + test(not isinstance(p, Test.PSUnknown2)) + test(p.pi == 5) + test(p.ps == "preserved") + else: + test(isinstance(p, Test.PSUnknown2)) + test(p.pi == 5) + test(p.ps == "preserved") + test(p.pb == p) + p.pb = None # Break the cycle. + cb.ice_response() + + def exchangePNode_async(self, cb, pn, current=None): + cb.ice_response(pn) + + def throwBaseAsBase_async(self, cb, current=None): + be = Test.BaseException() + be.sbe = "sbe" + be.pb = Test.B() + be.pb.sb = "sb" + be.pb.pb = be.pb + cb.ice_exception(be) + + def throwDerivedAsBase_async(self, cb, current=None): + de = Test.DerivedException() + de.sbe = "sbe" + de.pb = Test.B() + de.pb.sb = "sb1" + de.pb.pb = de.pb + de.sde = "sde1" + de.pd1 = Test.D1() + de.pd1.sb = "sb2" + de.pd1.pb = de.pd1 + de.pd1.sd1 = "sd2" + de.pd1.pd1 = de.pd1 + cb.ice_exception(de) + + def throwDerivedAsDerived_async(self, cb, current=None): + de = Test.DerivedException() + de.sbe = "sbe" + de.pb = Test.B() + de.pb.sb = "sb1" + de.pb.pb = de.pb + de.sde = "sde1" + de.pd1 = Test.D1() + de.pd1.sb = "sb2" + de.pd1.pb = de.pd1 + de.pd1.sd1 = "sd2" + de.pd1.pd1 = de.pd1 + cb.ice_exception(de) + + def throwUnknownDerivedAsBase_async(self, cb, current=None): + d2 = Test.D2() + d2.sb = "sb d2" + d2.pb = d2 + d2.sd2 = "sd2 d2" + d2.pd2 = d2 + + ude = Test.UnknownDerivedException() + ude.sbe = "sbe" + ude.pb = d2 + ude.sude = "sude" + ude.pd2 = d2 + cb.ice_exception(ude) + + def throwPreservedException_async(self, cb, current=None): + ue = Test.PSUnknownException() + ue.p = Test.PSUnknown2() + ue.p.pi = 5 + ue.p.ps = "preserved" + ue.p.pb = ue.p + cb.ice_exception(ue) + ue.p.pb = None # Break the cycle. + + def useForward_async(self, cb, current=None): + f = Test.Forward() + f.h = Test.Hidden() + f.h.f = f + cb.ice_response(f) + + def shutdown_async(self, cb, current=None): + current.adapter.getCommunicator().shutdown() + cb.ice_response() + +def run(args, communicator): + properties = communicator.getProperties() + properties.setProperty("Ice.Warn.Dispatch", "0") + properties.setProperty("TestAdapter.Endpoints", "default -p 12010 -t 10000") + adapter = communicator.createObjectAdapter("TestAdapter") + object = TestI() + adapter.add(object, communicator.stringToIdentity("Test")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + communicator = Ice.initialize(sys.argv) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/slicing/objects/ServerPrivate.ice b/python/test/Ice/slicing/objects/ServerPrivate.ice new file mode 100644 index 00000000000..f4eb9552f0f --- /dev/null +++ b/python/test/Ice/slicing/objects/ServerPrivate.ice @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <Test.ice> + +module Test +{ + +class SBSUnknownDerived extends SBase +{ + string sbsud; +}; + +class SUnknown +{ + string su; +}; + +class D2 extends B +{ + string sd2; + B pd2; +}; + +class D4 extends B +{ + B p1; + B p2; +}; + +exception UnknownDerivedException extends BaseException +{ + string sude; + D2 pd2; +}; + +class MyClass +{ + int i; +}; + +class PSUnknown extends Preserved +{ + string psu; + PNode graph; + MyClass cl; +}; + +class PSUnknown2 extends Preserved +{ + PBase pb; +}; + +exception PSUnknownException extends PreservedException +{ + PSUnknown2 p; +}; + +}; diff --git a/python/test/Ice/slicing/objects/ServerPrivateAMD.ice b/python/test/Ice/slicing/objects/ServerPrivateAMD.ice new file mode 100644 index 00000000000..51746909b3f --- /dev/null +++ b/python/test/Ice/slicing/objects/ServerPrivateAMD.ice @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +#include <TestAMD.ice> + +module Test +{ + +class SBSUnknownDerived extends SBase +{ + string sbsud; +}; + +class SUnknown +{ + string su; +}; + +class D2 extends B +{ + string sd2; + B pd2; +}; + +class D4 extends B +{ + B p1; + B p2; +}; + +exception UnknownDerivedException extends BaseException +{ + string sude; + D2 pd2; +}; + +class MyClass +{ + int i; +}; + +class PSUnknown extends Preserved +{ + string psu; + PNode graph; + MyClass cl; +}; + +class PSUnknown2 extends Preserved +{ + PBase pb; +}; + +exception PSUnknownException extends PreservedException +{ + PSUnknown2 p; +}; + +}; diff --git a/python/test/Ice/slicing/objects/Test.ice b/python/test/Ice/slicing/objects/Test.ice new file mode 100644 index 00000000000..3b1d13db6bd --- /dev/null +++ b/python/test/Ice/slicing/objects/Test.ice @@ -0,0 +1,164 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class SBase +{ + string sb; +}; + +class SBSKnownDerived extends SBase +{ + string sbskd; +}; + +class B +{ + string sb; + B pb; +}; + +class D1 extends B +{ + string sd1; + B pd1; +}; + +sequence<B> BSeq; + +class SS1 +{ + BSeq s; +}; + +class SS2 +{ + BSeq s; +}; + +struct SS3 +{ + SS1 c1; + SS2 c2; +}; + +dictionary<int, B> BDict; + +exception BaseException +{ + string sbe; + B pb; +}; + +exception DerivedException extends BaseException +{ + string sde; + D1 pd1; +}; + +class Forward; /* Forward-declared class defined in another compilation unit */ + +class PBase +{ + int pi; +}; + +sequence<PBase> PBaseSeq; + +["preserve-slice"] +class Preserved extends PBase +{ + string ps; +}; + +class PDerived extends Preserved +{ + PBase pb; +}; + +class CompactPDerived(56) extends Preserved +{ + PBase pb; +}; + +["preserve-slice"] +class PNode +{ + PNode next; +}; + +["preserve-slice"] +exception PreservedException +{ +}; + +["format:sliced"] +interface TestIntf +{ + Object SBaseAsObject(); + SBase SBaseAsSBase(); + SBase SBSKnownDerivedAsSBase(); + SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived(); + + SBase SBSUnknownDerivedAsSBase(); + + ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact(); + + Object SUnknownAsObject(); + void checkSUnknown(Object o); + + B oneElementCycle(); + B twoElementCycle(); + B D1AsB(); + D1 D1AsD1(); + B D2AsB(); + + void paramTest1(out B p1, out B p2); + void paramTest2(out B p2, out B p1); + B paramTest3(out B p1, out B p2); + B paramTest4(out B p); + + B returnTest1(out B p1, out B p2); + B returnTest2(out B p2, out B p1); + B returnTest3(B p1, B p2); + + SS3 sequenceTest(SS1 p1, SS2 p2); + + BDict dictionaryTest(BDict bin, out BDict bout); + + PBase exchangePBase(PBase pb); + + Preserved PBSUnknownAsPreserved(); + void checkPBSUnknown(Preserved p); + + ["amd"] Preserved PBSUnknownAsPreservedWithGraph(); + void checkPBSUnknownWithGraph(Preserved p); + + ["amd"] Preserved PBSUnknown2AsPreservedWithGraph(); + void checkPBSUnknown2WithGraph(Preserved p); + + PNode exchangePNode(PNode pn); + + void throwBaseAsBase() throws BaseException; + void throwDerivedAsBase() throws BaseException; + void throwDerivedAsDerived() throws DerivedException; + void throwUnknownDerivedAsBase() throws BaseException; + ["amd"] void throwPreservedException() throws PreservedException; + + void useForward(out Forward f); /* Use of forward-declared class to verify that code is generated correctly. */ + + void shutdown(); +}; + +}; + diff --git a/python/test/Ice/slicing/objects/TestAMD.ice b/python/test/Ice/slicing/objects/TestAMD.ice new file mode 100644 index 00000000000..0d6f7eefb78 --- /dev/null +++ b/python/test/Ice/slicing/objects/TestAMD.ice @@ -0,0 +1,158 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +class SBase +{ + string sb; +}; + +class SBSKnownDerived extends SBase +{ + string sbskd; +}; + +class B +{ + string sb; + B pb; +}; + +class D1 extends B +{ + string sd1; + B pd1; +}; + +sequence<B> BSeq; + +class SS1 +{ + BSeq s; +}; + +class SS2 +{ + BSeq s; +}; + +struct SS3 +{ + SS1 c1; + SS2 c2; +}; + +dictionary<int, B> BDict; + +exception BaseException +{ + string sbe; + B pb; +}; + +exception DerivedException extends BaseException +{ + string sde; + D1 pd1; +}; + +class Forward; // Forward-declared class defined in another compilation unit + +class PBase +{ + int pi; +}; + +sequence<PBase> PBaseSeq; + +["preserve-slice"] +class Preserved extends PBase +{ + string ps; +}; + +class PDerived extends Preserved +{ + PBase pb; +}; + +["preserve-slice"] +class PNode +{ + PNode next; +}; + +["preserve-slice"] +exception PreservedException +{ +}; + +["amd", "format:sliced"] +interface TestIntf +{ + Object SBaseAsObject(); + SBase SBaseAsSBase(); + SBase SBSKnownDerivedAsSBase(); + SBSKnownDerived SBSKnownDerivedAsSBSKnownDerived(); + + SBase SBSUnknownDerivedAsSBase(); + + ["format:compact"] SBase SBSUnknownDerivedAsSBaseCompact(); + + Object SUnknownAsObject(); + void checkSUnknown(Object o); + + B oneElementCycle(); + B twoElementCycle(); + B D1AsB(); + D1 D1AsD1(); + B D2AsB(); + + void paramTest1(out B p1, out B p2); + void paramTest2(out B p2, out B p1); + B paramTest3(out B p1, out B p2); + B paramTest4(out B p); + + B returnTest1(out B p1, out B p2); + B returnTest2(out B p2, out B p1); + B returnTest3(B p1, B p2); + + SS3 sequenceTest(SS1 p1, SS2 p2); + + BDict dictionaryTest(BDict bin, out BDict bout); + + PBase exchangePBase(PBase pb); + + Preserved PBSUnknownAsPreserved(); + void checkPBSUnknown(Preserved p); + + Preserved PBSUnknownAsPreservedWithGraph(); + void checkPBSUnknownWithGraph(Preserved p); + + Preserved PBSUnknown2AsPreservedWithGraph(); + void checkPBSUnknown2WithGraph(Preserved p); + + PNode exchangePNode(PNode pn); + + void throwBaseAsBase() throws BaseException; + void throwDerivedAsBase() throws BaseException; + void throwDerivedAsDerived() throws DerivedException; + void throwUnknownDerivedAsBase() throws BaseException; + void throwPreservedException() throws PreservedException; + + void useForward(out Forward f); /* Use of forward-declared class to verify that code is generated correctly. */ + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/slicing/objects/run.py b/python/test/Ice/slicing/objects/run.py new file mode 100755 index 00000000000..a2cb1c4544e --- /dev/null +++ b/python/test/Ice/slicing/objects/run.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../..", "../../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +print("Running test with sliced format.") +TestUtil.clientServerTest() + +print("Running test with 1.0 encoding.") +TestUtil.clientServerTest(additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") + +print("Running test with sliced format and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py") + +print("Running test with 1.0 encoding and AMD server.") +TestUtil.clientServerTest(server="ServerAMD.py", + additionalClientOptions="--Ice.Default.EncodingVersion=1.0", + additionalServerOptions="--Ice.Default.EncodingVersion=1.0") diff --git a/python/test/Ice/timeout/AllTests.py b/python/test/Ice/timeout/AllTests.py new file mode 100644 index 00000000000..d9db6f705b1 --- /dev/null +++ b/python/test/Ice/timeout/AllTests.py @@ -0,0 +1,259 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import Ice, Test, sys, threading, time + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +class CallbackBase: + def __init__(self): + self._called = False + self._cond = threading.Condition() + + def called(self): + self._cond.acquire() + self._called = True + self._cond.notify() + self._cond.release() + + def check(self): + self._cond.acquire() + while not self._called: + self._cond.wait() + self._called = False + return True + +class Callback(CallbackBase): + def response(self): + self.called() + + def exception(self, ex): + test(False) + + def responseEx(self): + test(False) + + def exceptionEx(self, ex): + test(isinstance(ex, Ice.TimeoutException)) + self.called() + +def allTests(communicator): + sref = "timeout:default -p 12010" + obj = communicator.stringToProxy(sref) + test(obj != None) + + timeout = Test.TimeoutPrx.checkedCast(obj) + test(timeout != None) + + sys.stdout.write("testing connect timeout... ") + sys.stdout.flush() + # + # Expect ConnectTimeoutException. + # + to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(100)) + timeout.holdAdapter(500) + try: + to.op() + test(False) + except Ice.ConnectTimeoutException: + pass # Expected. + # + # Expect success. + # + timeout.op() # Ensure adapter is active. + to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(1000)) + timeout.holdAdapter(500) + try: + to.op() + except Ice.ConnectTimeoutException: + test(False) + print("ok") + + sys.stdout.write("testing connection timeout... ") + sys.stdout.flush() + # + # Expect TimeoutException. + # + if sys.version_info[0] == 2: + seq = [] + seq[0:10000000] = range(0, 10000000) # add 10,000,000 entries. + seq = ['\x00' for x in seq] # set them all to \x00 + seq = ''.join(seq) # make into a byte array + else: + seq = bytes([0 for x in range(0, 10000000)]) + to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(100)) + timeout.holdAdapter(500) + try: + to.sendData(seq) + test(False) + except Ice.TimeoutException: + pass # Expected. + # + # Expect success. + # + timeout.op() # Ensure adapter is active. + to = Test.TimeoutPrx.uncheckedCast(obj.ice_timeout(1000)) + timeout.holdAdapter(500) + try: + if sys.version_info[0] == 2: + seq2 = [] + seq2[0:1000000] = range(0, 1000000) # add 1,000,000 entries. + seq2 = ['\x00' for x in seq2] # set them all to \x00 + seq2 = ''.join(seq2) # make into a byte array + else: + seq2 = bytes([0 for x in range(0, 1000000)]) + to.sendData(seq2) + except Ice.TimeoutException: + test(False) + print("ok") + + sys.stdout.write("testing invocation timeout... ") + sys.stdout.flush() + connection = obj.ice_getConnection(); + to = Test.TimeoutPrx.uncheckedCast(obj.ice_invocationTimeout(100)); + test(connection == to.ice_getConnection()); + try: + to.sleep(750); + test(False); + except Ice.InvocationTimeoutException: + pass + obj.ice_ping(); + to = Test.TimeoutPrx.uncheckedCast(obj.ice_invocationTimeout(500)); + test(connection == to.ice_getConnection()); + try: + to.sleep(250); + except Ice.InvocationTimeoutException: + test(False); + test(connection == to.ice_getConnection()); + + # # + # # Expect InvocationTimeoutException. + # # + # to = Test.TimeoutPrx.uncheckedCast(obj.ice_invocationTimeout(250)); + # cb = new Callback(); + # to.begin_sleep(750, newCallback_Timeout_sleep(cb, &Callback.responseEx, &Callback.exceptionEx)); + # cb.check(); + + # # + # # Expect success. + # # + # to = Test.TimeoutPrx.uncheckedCast(obj.ice_invocationTimeout(500)); + # cb = new Callback(); + # to.begin_sleep(250, newCallback_Timeout_sleep(cb, &Callback.response, &Callback.exception)); + # cb.check(); + print("ok") + + sys.stdout.write("testing close timeout... ") + sys.stdout.flush() + to = Test.TimeoutPrx.checkedCast(obj.ice_timeout(100)); + connection = to.ice_getConnection(); + timeout.holdAdapter(500); + connection.close(False); + try: + connection.getInfo(); # getInfo() doesn't throw in the closing state. + except Ice.LocalException: + test(False); + time.sleep(0.5); + try: + connection.getInfo(); + test(False); + except Ice.CloseConnectionException: + # Expected. + pass + timeout.op(); # Ensure adapter is active. + print("ok") + + sys.stdout.write("testing timeout overrides... ") + sys.stdout.flush() + + # + # Test Ice.Override.Timeout. This property overrides all + # endpoint timeouts. + # + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + initData.properties.setProperty("Ice.Override.Timeout", "100") + comm = Ice.initialize(initData) + to = Test.TimeoutPrx.checkedCast(comm.stringToProxy(sref)) + timeout.holdAdapter(500) + try: + to.sendData(seq) + test(False) + except Ice.TimeoutException: + pass # Expected. + # + # Calling ice_timeout() should have no effect. + # + timeout.op() # Ensure adapter is active. + to = Test.TimeoutPrx.checkedCast(to.ice_timeout(1000)) + timeout.holdAdapter(500); + try: + to.sendData(seq) + test(False) + except Ice.TimeoutException: + pass # Expected. + comm.destroy() + # + # Test Ice.Override.ConnectTimeout. + # + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + initData.properties.setProperty("Ice.Override.ConnectTimeout", "250") + comm = Ice.initialize(initData) + timeout.holdAdapter(750) + to = Test.TimeoutPrx.uncheckedCast(comm.stringToProxy(sref)) + try: + to.op() + test(False) + except Ice.ConnectTimeoutException: + pass # Expected. + # + # Calling ice_timeout() should have no effect on the connect timeout. + # + timeout.op() # Ensure adapter is active. + timeout.holdAdapter(750) + to = Test.TimeoutPrx.uncheckedCast(to.ice_timeout(1000)) + try: + to.op() + test(False) + except Ice.ConnectTimeoutException: + pass # Expected. + # + # Verify that timeout set via ice_timeout() is still used for requests. + # + timeout.op() # Ensure adapter is active. + to = Test.TimeoutPrx.uncheckedCast(to.ice_timeout(100)); + to.ice_getConnection(); # Establish connection + timeout.holdAdapter(750); + try: + to.sendData(seq) + test(False) + except Ice.TimeoutException: + pass # Expected. + comm.destroy() + + # + # Test Ice.Override.CloseTimeout. + # + initData = Ice.InitializationData() + initData.properties = communicator.getProperties().clone() + initData.properties.setProperty("Ice.Override.CloseTimeout", "100") + comm = Ice.initialize(initData) + connection = comm.stringToProxy(sref).ice_getConnection(); + timeout.holdAdapter(500); + now = time.clock(); + comm.destroy(); + test((time.clock() - now) < 0.4); + + print("ok") + + + return timeout diff --git a/python/test/Ice/timeout/Client.py b/python/test/Ice/timeout/Client.py new file mode 100755 index 00000000000..0cee6a61c9e --- /dev/null +++ b/python/test/Ice/timeout/Client.py @@ -0,0 +1,74 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import AllTests + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def run(args, communicator): + timeout = AllTests.allTests(communicator) + timeout.shutdown() + + return True + +try: + # + # In this test, we need at least two threads in the + # client side thread pool for nested AMI. + # + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + + # + # We need to send messages large enough to cause the transport + # buffers to fill up. + # + initData.properties.setProperty("Ice.MessageSizeMax", "10000"); + + # + # For this test, we want to disable retries. + # + initData.properties.setProperty("Ice.RetryIntervals", "-1"); + + # + # This test kills connections, so we don't want warnings. + # + initData.properties.setProperty("Ice.Warn.Connections", "0"); + + # + # Limit the send buffer size, this test relies on the socket + # send() blocking after sending a given amount of data. + # + initData.properties.setProperty("Ice.TCP.SndSize", "50000"); + + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/timeout/Server.py b/python/test/Ice/timeout/Server.py new file mode 100755 index 00000000000..058491d9011 --- /dev/null +++ b/python/test/Ice/timeout/Server.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback, time, threading + +import Ice +slice_dir = Ice.getSliceDir() +if not slice_dir: + print(sys.argv[0] + ': Slice directory not found.') + sys.exit(1) + +Ice.loadSlice("'-I" + slice_dir + "' Test.ice") +import Test + +class ActivateAdapterThread(threading.Thread): + def __init__(self, adapter, timeout): + threading.Thread.__init__(self) + self._adapter = adapter + self._timeout = timeout + + def run(self): + time.sleep(self._timeout / 1000.0) + self._adapter.activate() + +class TimeoutI(Test.Timeout): + def op(self, current=None): + pass + + def sendData(self, data, current=None): + pass + + def sleep(self, timeout, current=None): + if timeout != 0: + time.sleep(timeout / 1000.0) + + def holdAdapter(self, to, current=None): + current.adapter.hold() + t = ActivateAdapterThread(current.adapter, to) + t.start() + + def shutdown(self, current=None): + current.adapter.getCommunicator().shutdown() + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(TimeoutI(), communicator.stringToIdentity("timeout")) + adapter.activate() + communicator.waitForShutdown() + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + initData.properties.setProperty("Ice.Warn.Connections", "0"); + # + # Limit the recv buffer size, this test relies on the socket + # send() blocking after sending a given amount of data. + # + initData.properties.setProperty("Ice.TCP.RcvSize", "50000"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Ice/timeout/Test.ice b/python/test/Ice/timeout/Test.ice new file mode 100644 index 00000000000..dc54d71c16c --- /dev/null +++ b/python/test/Ice/timeout/Test.ice @@ -0,0 +1,28 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +#pragma once + +module Test +{ + +sequence<byte> ByteSeq; + +interface Timeout +{ + void op(); + void sendData(ByteSeq seq); + void sleep(int to); + + void holdAdapter(int to); + + void shutdown(); +}; + +}; diff --git a/python/test/Ice/timeout/run.py b/python/test/Ice/timeout/run.py new file mode 100755 index 00000000000..74d2e5d1724 --- /dev/null +++ b/python/test/Ice/timeout/run.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +TestUtil.clientServerTest() diff --git a/python/test/Makefile b/python/test/Makefile new file mode 100644 index 00000000000..23caa0e5bda --- /dev/null +++ b/python/test/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = Slice + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/python/test/Makefile.mak b/python/test/Makefile.mak new file mode 100644 index 00000000000..9830e50eb83 --- /dev/null +++ b/python/test/Makefile.mak @@ -0,0 +1,19 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = .. + +!include $(top_srcdir)\config\Make.rules.mak + +SUBDIRS = Slice + +$(EVERYTHING):: + @for %i in ( $(SUBDIRS) ) do \ + @echo "making $@ in %i" && \ + cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1 diff --git a/python/test/Slice/Makefile b/python/test/Slice/Makefile new file mode 100644 index 00000000000..19f18553195 --- /dev/null +++ b/python/test/Slice/Makefile @@ -0,0 +1,21 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../.. + +include $(top_srcdir)/config/Make.rules + +SUBDIRS = import + +$(EVERYTHING):: + @for subdir in $(SUBDIRS); \ + do \ + echo "making $@ in $$subdir"; \ + ( cd $$subdir && $(MAKE) $@ ) || exit 1; \ + done diff --git a/python/test/Slice/Makefile.mak b/python/test/Slice/Makefile.mak new file mode 100644 index 00000000000..2646dddc07c --- /dev/null +++ b/python/test/Slice/Makefile.mak @@ -0,0 +1,19 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ..\.. + +!include $(top_srcdir)\config\Make.rules.mak + +SUBDIRS = import + +$(EVERYTHING):: + @for %i in ( $(SUBDIRS) ) do \ + @echo "making $@ in %i" && \ + cmd /c "cd %i && $(MAKE) -nologo -f Makefile.mak $@" || exit 1 diff --git a/python/test/Slice/import/.depend.mak b/python/test/Slice/import/.depend.mak new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/python/test/Slice/import/.depend.mak diff --git a/python/test/Slice/import/.gitignore b/python/test/Slice/import/.gitignore new file mode 100644 index 00000000000..88325c99134 --- /dev/null +++ b/python/test/Slice/import/.gitignore @@ -0,0 +1,3 @@ +Test1_ice.py +Test2_ice.py +Test diff --git a/python/test/Slice/import/Client.py b/python/test/Slice/import/Client.py new file mode 100755 index 00000000000..a8f9a1956b0 --- /dev/null +++ b/python/test/Slice/import/Client.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "python", "Ice.py")): + break +else: + raise RuntimeError("can't find toplevel directory!") + +import Test + +status = True + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +try: + sys.stdout.write("testing imports... ") + sys.stdout.flush() + + test(Test.SubA.SubSubA1.Value1 == 10) + test(Test.SubA.SubSubA1.Value2 == 11) + test(Test.SubA.SubSubA2.Value1 == 30) + test(Test.SubB.SubSubB1.Value1 == 20) + test(Test.SubB.SubSubB1.Value2 == 21) + + print("ok") +except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Slice/import/Makefile b/python/test/Slice/import/Makefile new file mode 100644 index 00000000000..91581b604f5 --- /dev/null +++ b/python/test/Slice/import/Makefile @@ -0,0 +1,32 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ../../.. + +include $(top_srcdir)/config/Make.rules + +# +# Parallel builds are not supported because multiple executions of slice2py could +# attempt to modify the __init__.py file simultaneously. +# +.NOTPARALLEL: + +SRCS = Test1_ice.py \ + Test2_ice.py + +all:: $(SRCS) + +Test1_ice.py: Test1.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) $(SLICE2PYFLAGS) $< + +Test2_ice.py: Test2.ice $(SLICE2PY) $(SLICEPARSERLIB) + $(SLICE2PY) $(SLICE2PYFLAGS) $< + +clean:: + rm -rf $(SRCS) Test diff --git a/python/test/Slice/import/Makefile.mak b/python/test/Slice/import/Makefile.mak new file mode 100644 index 00000000000..f56fb6a3d87 --- /dev/null +++ b/python/test/Slice/import/Makefile.mak @@ -0,0 +1,29 @@ +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +top_srcdir = ..\..\.. + +!include $(top_srcdir)\config\Make.rules.mak + +SRCS = Test1_ice.py \ + Test2_ice.py + +all:: $(SRCS) + +Test1_ice.py: "Test1.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) "Test1.ice" + +Test2_ice.py: "Test2.ice" "$(SLICE2PY)" "$(SLICEPARSERLIB)" + "$(SLICE2PY)" $(SLICE2PYFLAGS) "Test2.ice" + +clean:: + -rmdir /s /q Test + del /q $(SRCS) + +include .depend.mak diff --git a/python/test/Slice/import/Test1.ice b/python/test/Slice/import/Test1.ice new file mode 100644 index 00000000000..48f6af92c8e --- /dev/null +++ b/python/test/Slice/import/Test1.ice @@ -0,0 +1,27 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +module Test +{ + module SubA + { + module SubSubA1 + { + const int Value1 = 10; + }; + }; + + module SubB + { + module SubSubB1 + { + const int Value1 = 20; + }; + }; +}; diff --git a/python/test/Slice/import/Test2.ice b/python/test/Slice/import/Test2.ice new file mode 100644 index 00000000000..4cd0913081c --- /dev/null +++ b/python/test/Slice/import/Test2.ice @@ -0,0 +1,31 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +module Test +{ + module SubA + { + module SubSubA1 + { + const int Value2 = 11; + }; + module SubSubA2 + { + const int Value1 = 30; + }; + }; + + module SubB + { + module SubSubB1 + { + const int Value2 = 21; + }; + }; +}; diff --git a/python/test/Slice/import/run.py b/python/test/Slice/import/run.py new file mode 100755 index 00000000000..2054bdd7692 --- /dev/null +++ b/python/test/Slice/import/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", "--Ice.Default.Host=127.0.0.1", startReader = False) +print("ok") +clientProc.startReader() +clientProc.waitTestSuccess() diff --git a/python/test/Slice/keyword/Client.py b/python/test/Slice/keyword/Client.py new file mode 100755 index 00000000000..82560627c27 --- /dev/null +++ b/python/test/Slice/keyword/Client.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "python", "Ice.py")): + break +else: + raise RuntimeError("can't find toplevel directory!") + +import Ice + +Ice.loadSlice('Key.ice') +import _and + +class delI(_and._del): + def _elif_async(self, _cb, _else, current=None): + pass + +class execI(_and._exec): + def _finally(self, current=None): + assert current.operation == "finally" + +class forI(_and._for): + def foo(self, _from, current=None): + pass + +class ifI(_and._if): + def _elif_async(self, _cb, _else, current=None): + pass + def _finally(self, current=None): + pass + def foo(self, _from, current=None): + pass + +class printI(_and._print): + def _raise(self, _else, _return, _try, _while, _yield, _lambda, _or, _global): + pass + +def testtypes(): + sys.stdout.write("Testing generated type names... ") + sys.stdout.flush() + a = _and._assert._break + b = _and._continue + b._def = 0 + c = _and.delPrx.uncheckedCast(None) + assert "_elif" in dir(_and.delPrx) + c1 = delI() + d = _and.execPrx.uncheckedCast(None) + assert "_finally" in dir(_and.execPrx) + d1 = execI() + + e1 = forI() + f = _and.ifPrx.uncheckedCast(None) + + assert "_finally" in dir(_and.ifPrx) + assert "_elif" in dir(_and.ifPrx) + f1 = ifI() + g = _and._is() + g._lamba = 0 + h = _and._not() + h._lamba = 0 + h._or = 1 + h._pass = 2 + i = printI() + j = _and._lambda; + en = _and.EnumNone._None + print("ok") + +def run(args, communicator): + communicator.getProperties().setProperty("TestAdapter.Endpoints", "default -p 12010:udp") + adapter = communicator.createObjectAdapter("TestAdapter") + adapter.add(execI(), communicator.stringToIdentity("test")) + adapter.activate() + + sys.stdout.write("Testing operation name... ") + sys.stdout.flush() + p = _and.execPrx.uncheckedCast( + adapter.createProxy(communicator.stringToIdentity("test"))); + p._finally(); + print("ok") + + testtypes() + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + # + # Its possible to have batch oneway requests dispatched after the + # adapter is deactivated due to thread scheduling so we supress + # this warning. + # + initData.properties.setProperty("Ice.Warn.Dispatch", "0"); + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Slice/keyword/Key.ice b/python/test/Slice/keyword/Key.ice new file mode 100644 index 00000000000..6e46ad0748c --- /dev/null +++ b/python/test/Slice/keyword/Key.ice @@ -0,0 +1,67 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +module and +{ + enum assert + { + break + }; + + struct continue + { + int def; + }; + + interface del + { + ["amd"] void elif(int else, out int except); + }; + + interface exec + { + void finally(); + }; + + class for + { + int lambda; + void foo(exec* from, out int global); + }; + + class if extends for implements exec, del + { + }; + + sequence<assert> import; + dictionary<string,assert> in; + + exception is + { + int lambda; + }; + exception not extends is + { + int or; + int pass; + }; + + local interface print + { + assert raise(continue else, for return, if try, del* while, exec* yield, + for* lambda, if* or, int global) + throws is; + }; + + const int lambda = 0; + + enum EnumNone { + None + }; +}; diff --git a/python/test/Slice/keyword/run.py b/python/test/Slice/keyword/run.py new file mode 100755 index 00000000000..2054bdd7692 --- /dev/null +++ b/python/test/Slice/keyword/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", "--Ice.Default.Host=127.0.0.1", startReader = False) +print("ok") +clientProc.startReader() +clientProc.waitTestSuccess() diff --git a/python/test/Slice/macros/Client.py b/python/test/Slice/macros/Client.py new file mode 100755 index 00000000000..a64d7faf9b0 --- /dev/null +++ b/python/test/Slice/macros/Client.py @@ -0,0 +1,51 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "python", "Ice.py")): + break +else: + raise RuntimeError("can't find toplevel directory!") + +import Ice + +Ice.loadSlice('Test.ice') +import Test, copy + +status = True + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +try: + sys.stdout.write("testing Slice predefined macros... ") + sys.stdout.flush() + + d = Test.Default() + test(d.x == 10) + test(d.y == 10) + + nd = Test.NoDefault() + test(nd.x != 10) + test(nd.y != 10) + + c = Test.PythonOnly() + test(c.lang == "python") + test(c.version == Ice.intVersion()) + print("ok") +except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Slice/macros/Test.ice b/python/test/Slice/macros/Test.ice new file mode 100644 index 00000000000..825c641fffa --- /dev/null +++ b/python/test/Slice/macros/Test.ice @@ -0,0 +1,54 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +// +// This macro sets the default value only when compiling with slice2py. +// +#ifdef __SLICE2PY__ +# define DEFAULT(X) = X +#else +# define DEFAULT(X) /**/ +#endif + +// +// This macro sets the default value only when not compiling with slice2py. +// +#ifndef __SLICE2PY__ +# define NODEFAULT(X) = X +#else +# define NODEFAULT(X) /**/ +#endif + +module Test +{ + +class Default +{ + int x DEFAULT(10); + int y DEFAULT(10); +}; + +class NoDefault +{ + int x NODEFAULT(10); + int y NODEFAULT(10); +}; + +// +// This class is only defined when compiling with slice2py. +// +#ifdef __SLICE2PY__ +class PythonOnly +{ + string lang DEFAULT("python"); + int version DEFAULT(ICE_VERSION); +}; +#endif + +}; diff --git a/python/test/Slice/macros/run.py b/python/test/Slice/macros/run.py new file mode 100755 index 00000000000..2054bdd7692 --- /dev/null +++ b/python/test/Slice/macros/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", "--Ice.Default.Host=127.0.0.1", startReader = False) +print("ok") +clientProc.startReader() +clientProc.waitTestSuccess() diff --git a/python/test/Slice/structure/Client.py b/python/test/Slice/structure/Client.py new file mode 100755 index 00000000000..036ce2121d1 --- /dev/null +++ b/python/test/Slice/structure/Client.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys, traceback + +for toplevel in [".", "..", "../..", "../../..", "../../../.."]: + toplevel = os.path.normpath(toplevel) + if os.path.exists(os.path.join(toplevel, "python", "Ice.py")): + break +else: + raise RuntimeError("can't find toplevel directory!") + +import Ice + +Ice.loadSlice('Test.ice') +import Test, copy + +def test(b): + if not b: + raise RuntimeError('test assertion failed') + +def allTests(communicator): + sys.stdout.write("testing equals() for Slice structures... ") + sys.stdout.flush() + + # + # Define some default values. + # + def_s2 = Test.S2(True, 98, 99, 100, 101, "string", (1, 2, 3), Test.S1("name")) + + # + # Compare default-constructed structures. + # + test(Test.S2() == Test.S2()) + + # + # Change one member at a time. + # + v = copy.copy(def_s2) + test(v == def_s2) + + v = copy.copy(def_s2) + v.bo = False + test(v != def_s2) + + v = copy.copy(def_s2) + v.by = v.by - 1 + test(v != def_s2) + + v = copy.copy(def_s2) + v.sh = v.sh - 1 + test(v != def_s2) + + v = copy.copy(def_s2) + v.i = v.i - 1 + test(v != def_s2) + + v = copy.copy(def_s2) + v.l = v.l - 1 + test(v != def_s2) + + v = copy.copy(def_s2) + v.str = "" + test(v != def_s2) + + # + # String member + # + v1 = copy.copy(def_s2) + v1.str = "string" + test(v1 == def_s2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v1.str = None + test(v1 != v2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v2.str = None + test(v1 != v2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v1.str = None + v2.str = None + test(v1 == v2) + + # + # Sequence member + # + v1 = copy.copy(def_s2) + v1.seq = copy.copy(def_s2.seq) + test(v1 == def_s2) + + v1 = copy.copy(def_s2) + v1.seq = () + test(v1 != def_s2) + + v1 = copy.copy(def_s2) + v1.seq = (1, 2, 3) + test(v1 == def_s2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v1.seq = None + test(v1 != v2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v2.seq = None + test(v1 != v2) + + # + # Struct member + # + v1 = copy.copy(def_s2) + v1.s = copy.copy(def_s2.s) + test(v1 == def_s2) + + v1 = copy.copy(def_s2) + v1.s = Test.S1("name") + test(v1 == def_s2) + + v1 = copy.copy(def_s2) + v1.s = Test.S1("noname") + test(v1 != def_s2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v1.s = None + test(v1 != v2) + + v1 = copy.copy(def_s2) + v2 = copy.copy(def_s2) + v2.s = None + test(v1 != v2) + + # + # Define some default values. + # + def_s3 = Test.S3(Test.C("name"), {"1":"2"}, communicator.stringToProxy("test")) + + # + # Compare default-constructed structures. + # + test(Test.S3() == Test.S3()) + + # + # Change one member at a time. + # + v1 = copy.copy(def_s3) + test(v1 == def_s3) + + v1.obj = None + test(v1 != def_s3) + + v1.obj = Test.C("name") + test(v1 != def_s3) + + v1 = copy.copy(def_s3) + v1.sd = copy.copy(def_s3.sd) + test(v1 == def_s3) + + v1.sd = None + test(v1 != def_s3) + + v1.sd = {"1":"3"} + test(v1 != def_s3) + + v1 = copy.copy(def_s3) + v1.prx = None + test(v1 != def_s3) + + v1.prx = communicator.stringToProxy("test") + test(v1 == def_s3) + + v1.prx = communicator.stringToProxy("test2") + test(v1 != def_s3) + + print("ok") + +def run(args, communicator): + allTests(communicator) + + return True + +try: + initData = Ice.InitializationData() + initData.properties = Ice.createProperties(sys.argv) + communicator = Ice.initialize(sys.argv, initData) + status = run(sys.argv, communicator) +except: + traceback.print_exc() + status = False + +if communicator: + try: + communicator.destroy() + except: + traceback.print_exc() + status = False + +sys.exit(not status) diff --git a/python/test/Slice/structure/Test.ice b/python/test/Slice/structure/Test.ice new file mode 100644 index 00000000000..973a80ad921 --- /dev/null +++ b/python/test/Slice/structure/Test.ice @@ -0,0 +1,47 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +[["cpp:include:list"]] + +module Test +{ + +sequence<int> IntSeq; +dictionary<string, string> StringDict; + +struct S1 +{ + string name; +}; + +struct S2 +{ + bool bo; + byte by; + short sh; + int i; + long l; + string str; + IntSeq seq; + S1 s; +}; + +class C +{ + string name; +}; + +struct S3 +{ + C obj; + StringDict sd; + Object* prx; +}; + +}; diff --git a/python/test/Slice/structure/run.py b/python/test/Slice/structure/run.py new file mode 100755 index 00000000000..2054bdd7692 --- /dev/null +++ b/python/test/Slice/structure/run.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python +# ********************************************************************** +# +# Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved. +# +# This copy of Ice is licensed to you under the terms described in the +# ICE_LICENSE file included in this distribution. +# +# ********************************************************************** + +import os, sys + +path = [ ".", "..", "../..", "../../..", "../../../.." ] +head = os.path.dirname(sys.argv[0]) +if len(head) > 0: + path = [os.path.join(head, p) for p in path] +path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ] +if len(path) == 0: + raise RuntimeError("can't find toplevel directory!") +sys.path.append(os.path.join(path[0], "scripts")) +import TestUtil + +sys.stdout.write("starting client... ") +sys.stdout.flush() +clientProc = TestUtil.startClient("Client.py", "--Ice.Default.Host=127.0.0.1", startReader = False) +print("ok") +clientProc.startReader() +clientProc.waitTestSuccess() |