summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2009-03-26 11:34:24 -0230
committerDwayne Boone <dwayne@zeroc.com>2009-03-26 11:34:24 -0230
commit0de45cd71fa21bcb20b8a3f754ff20cdf329ff23 (patch)
tree06c0fd3304362d39a56df0a234e90b3f84687edc /cpp
parentMore fixes to FixUtil.py (diff)
downloadice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.tar.bz2
ice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.tar.xz
ice-0de45cd71fa21bcb20b8a3f754ff20cdf329ff23.zip
Bug 2511 - add default servants
Diffstat (limited to 'cpp')
-rwxr-xr-xcpp/allTests.py1
-rw-r--r--cpp/src/Ice/ObjectAdapterI.cpp30
-rw-r--r--cpp/src/Ice/ObjectAdapterI.h4
-rw-r--r--cpp/src/Ice/ServantManager.cpp82
-rw-r--r--cpp/src/Ice/ServantManager.h6
-rw-r--r--cpp/test/Ice/Makefile3
-rw-r--r--cpp/test/Ice/Makefile.mak3
-rw-r--r--cpp/test/Ice/defaultServant/.depend3
-rw-r--r--cpp/test/Ice/defaultServant/.gitignore6
-rw-r--r--cpp/test/Ice/defaultServant/AllTests.cpp158
-rw-r--r--cpp/test/Ice/defaultServant/Client.cpp57
-rw-r--r--cpp/test/Ice/defaultServant/Makefile33
-rw-r--r--cpp/test/Ice/defaultServant/Makefile.mak39
-rw-r--r--cpp/test/Ice/defaultServant/Test.ice23
-rw-r--r--cpp/test/Ice/defaultServant/TestI.cpp45
-rw-r--r--cpp/test/Ice/defaultServant/TestI.h23
-rwxr-xr-xcpp/test/Ice/defaultServant/run.py25
17 files changed, 538 insertions, 3 deletions
diff --git a/cpp/allTests.py b/cpp/allTests.py
index 257a63c9da1..005db4d6f32 100755
--- a/cpp/allTests.py
+++ b/cpp/allTests.py
@@ -56,6 +56,7 @@ tests = [
("Ice/interceptor", ["core"]),
("Ice/stringConverter", ["core"]),
("Ice/udp", ["core"]),
+ ("Ice/defaultServant", ["core"]),
("IceSSL/configuration", ["once", "novalgrind"]), # valgrind doesn't work well with openssl
("IceBox/configuration", ["core", "noipv6"]),
("Freeze/dbmap", ["once"]),
diff --git a/cpp/src/Ice/ObjectAdapterI.cpp b/cpp/src/Ice/ObjectAdapterI.cpp
index 897ef753181..22832b15ac0 100644
--- a/cpp/src/Ice/ObjectAdapterI.cpp
+++ b/cpp/src/Ice/ObjectAdapterI.cpp
@@ -407,6 +407,16 @@ Ice::ObjectAdapterI::addFacetWithUUID(const ObjectPtr& object, const string& fac
return addFacet(object, ident, facet);
}
+void
+Ice::ObjectAdapterI::addDefaultServant(const ObjectPtr& servant, const string& category)
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ _servantManager->addDefaultServant(servant, category);
+}
+
ObjectPtr
Ice::ObjectAdapterI::remove(const Identity& ident)
{
@@ -436,6 +446,16 @@ Ice::ObjectAdapterI::removeAllFacets(const Identity& ident)
}
ObjectPtr
+Ice::ObjectAdapterI::removeDefaultServant(const string& category)
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ return _servantManager->removeDefaultServant(category);
+}
+
+ObjectPtr
Ice::ObjectAdapterI::find(const Identity& ident) const
{
return findFacet(ident, "");
@@ -474,6 +494,16 @@ Ice::ObjectAdapterI::findByProxy(const ObjectPrx& proxy) const
return findFacet(ref->getIdentity(), ref->getFacet());
}
+ObjectPtr
+Ice::ObjectAdapterI::findDefaultServant(const string& category) const
+{
+ IceUtil::Monitor<IceUtil::RecMutex>::Lock sync(*this);
+
+ checkForDeactivation();
+
+ return _servantManager->findDefaultServant(category);
+}
+
void
Ice::ObjectAdapterI::addServantLocator(const ServantLocatorPtr& locator, const string& prefix)
{
diff --git a/cpp/src/Ice/ObjectAdapterI.h b/cpp/src/Ice/ObjectAdapterI.h
index 58b2830e13f..5985dac062a 100644
--- a/cpp/src/Ice/ObjectAdapterI.h
+++ b/cpp/src/Ice/ObjectAdapterI.h
@@ -56,13 +56,17 @@ public:
virtual ObjectPrx addFacet(const ObjectPtr&, const Identity&, const std::string&);
virtual ObjectPrx addWithUUID(const ObjectPtr&);
virtual ObjectPrx addFacetWithUUID(const ObjectPtr&, const std::string&);
+ virtual void addDefaultServant(const ObjectPtr&, const std::string&);
virtual ObjectPtr remove(const Identity&);
virtual ObjectPtr removeFacet(const Identity&, const std::string&);
virtual FacetMap removeAllFacets(const Identity&);
+ virtual ObjectPtr removeDefaultServant(const std::string&);
virtual ObjectPtr find(const Identity&) const;
virtual ObjectPtr findFacet(const Identity&, const std::string&) const;
virtual FacetMap findAllFacets(const Identity&) const;
virtual ObjectPtr findByProxy(const ObjectPrx&) const;
+ virtual ObjectPtr findDefaultServant(const std::string&) const;
+
virtual void addServantLocator(const ServantLocatorPtr&, const std::string&);
virtual ServantLocatorPtr findServantLocator(const std::string&) const;
diff --git a/cpp/src/Ice/ServantManager.cpp b/cpp/src/Ice/ServantManager.cpp
index 743f0bdb6b9..6562896ae0a 100644
--- a/cpp/src/Ice/ServantManager.cpp
+++ b/cpp/src/Ice/ServantManager.cpp
@@ -58,6 +58,25 @@ IceInternal::ServantManager::addServant(const ObjectPtr& object, const Identity&
p->second.insert(pair<const string, ObjectPtr>(facet, object));
}
+void
+IceInternal::ServantManager::addDefaultServant(const ObjectPtr& object, const string& category)
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ assert(_instance); // Must not be called after destruction.
+
+ DefaultServantMap::iterator p = _defaultServantMap.find(category);
+ if(p != _defaultServantMap.end())
+ {
+ AlreadyRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ _defaultServantMap.insert(pair<const string, ObjectPtr>(category, object));
+}
+
ObjectPtr
IceInternal::ServantManager::removeServant(const Identity& ident, const string& facet)
{
@@ -110,6 +129,35 @@ IceInternal::ServantManager::removeServant(const Identity& ident, const string&
return servant;
}
+ObjectPtr
+IceInternal::ServantManager::removeDefaultServant(const string& category)
+{
+ //
+ // We return the removed servant to avoid releasing the last reference count
+ // with *this locked. We don't want to run user code, such as the servant
+ // destructor, with an internal Ice mutex locked.
+ //
+ ObjectPtr servant = 0;
+
+ IceUtil::Mutex::Lock sync(*this);
+
+ assert(_instance); // Must not be called after destruction.
+
+ DefaultServantMap::iterator p = _defaultServantMap.find(category);
+ if(p == _defaultServantMap.end())
+ {
+ NotRegisteredException ex(__FILE__, __LINE__);
+ ex.kindOfObject = "default servant";
+ ex.id = category;
+ throw ex;
+ }
+
+ servant = p->second;
+ _defaultServantMap.erase(p);
+
+ return servant;
+}
+
FacetMap
IceInternal::ServantManager::removeAllFacets(const Identity& ident)
{
@@ -172,7 +220,23 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa
if(p == servantMapMap.end() || (q = p->second.find(facet)) == p->second.end())
{
- return 0;
+ DefaultServantMap::const_iterator p = _defaultServantMap.find(ident.category);
+ if(p == _defaultServantMap.end())
+ {
+ p = _defaultServantMap.find("");
+ if(p == _defaultServantMap.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return p->second;
+ }
+ }
+ else
+ {
+ return p->second;
+ }
}
else
{
@@ -181,6 +245,22 @@ IceInternal::ServantManager::findServant(const Identity& ident, const string& fa
}
}
+ObjectPtr
+IceInternal::ServantManager::findDefaultServant(const string& category) const
+{
+ IceUtil::Mutex::Lock sync(*this);
+
+ DefaultServantMap::const_iterator p = _defaultServantMap.find(category);
+ if(p == _defaultServantMap.end())
+ {
+ return 0;
+ }
+ else
+ {
+ return p->second;
+ }
+}
+
FacetMap
IceInternal::ServantManager::findAllFacets(const Identity& ident) const
{
diff --git a/cpp/src/Ice/ServantManager.h b/cpp/src/Ice/ServantManager.h
index a06d050fa71..2cb1134e2e9 100644
--- a/cpp/src/Ice/ServantManager.h
+++ b/cpp/src/Ice/ServantManager.h
@@ -33,9 +33,12 @@ class ServantManager : public IceUtil::Shared, public IceUtil::Mutex
public:
void addServant(const Ice::ObjectPtr&, const Ice::Identity&, const std::string&);
+ void addDefaultServant(const Ice::ObjectPtr&, const std::string&);
Ice::ObjectPtr removeServant(const Ice::Identity&, const std::string&);
+ Ice::ObjectPtr removeDefaultServant(const std::string&);
Ice::FacetMap removeAllFacets(const Ice::Identity&);
Ice::ObjectPtr findServant(const Ice::Identity&, const std::string&) const;
+ Ice::ObjectPtr findDefaultServant(const std::string&) const;
Ice::FacetMap findAllFacets(const Ice::Identity&) const;
bool hasServant(const Ice::Identity&) const;
@@ -54,10 +57,13 @@ private:
const std::string _adapterName;
typedef std::map<Ice::Identity, Ice::FacetMap> ServantMapMap;
+ typedef std::map<std::string, Ice::ObjectPtr> DefaultServantMap;
ServantMapMap _servantMapMap;
mutable ServantMapMap::iterator _servantMapMapHint;
+ DefaultServantMap _defaultServantMap;
+
std::map<std::string, Ice::ServantLocatorPtr> _locatorMap;
mutable std::map<std::string, Ice::ServantLocatorPtr>::iterator _locatorMapHint;
};
diff --git a/cpp/test/Ice/Makefile b/cpp/test/Ice/Makefile
index f344aa259de..9eb14928c79 100644
--- a/cpp/test/Ice/Makefile
+++ b/cpp/test/Ice/Makefile
@@ -33,7 +33,8 @@ SUBDIRS = proxy \
interceptor \
stringConverter \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for subdir in $(SUBDIRS); \
diff --git a/cpp/test/Ice/Makefile.mak b/cpp/test/Ice/Makefile.mak
index 58f3c8aabac..728a96f3873 100644
--- a/cpp/test/Ice/Makefile.mak
+++ b/cpp/test/Ice/Makefile.mak
@@ -33,7 +33,8 @@ SUBDIRS = proxy \
interceptor \
stringConverter \
background \
- udp
+ udp \
+ defaultServant
$(EVERYTHING)::
@for %i in ( $(SUBDIRS) ) do \
diff --git a/cpp/test/Ice/defaultServant/.depend b/cpp/test/Ice/defaultServant/.depend
new file mode 100644
index 00000000000..e2f6cf95eff
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/.depend
@@ -0,0 +1,3 @@
+Test$(OBJEXT): Test.cpp ./Test.h $(includedir)/Ice/LocalObjectF.h $(includedir)/IceUtil/Shared.h $(includedir)/IceUtil/Config.h $(includedir)/Ice/Handle.h $(includedir)/IceUtil/Handle.h $(includedir)/IceUtil/Exception.h $(includedir)/Ice/Config.h $(includedir)/Ice/ProxyHandle.h $(includedir)/Ice/ProxyF.h $(includedir)/Ice/ObjectF.h $(includedir)/Ice/GCCountMap.h $(includedir)/Ice/GCShared.h $(includedir)/Ice/Exception.h $(includedir)/Ice/LocalObject.h $(includedir)/Ice/Proxy.h $(includedir)/IceUtil/Mutex.h $(includedir)/IceUtil/Lock.h $(includedir)/IceUtil/ThreadException.h $(includedir)/IceUtil/Time.h $(includedir)/Ice/ProxyFactoryF.h $(includedir)/Ice/ConnectionIF.h $(includedir)/Ice/RequestHandlerF.h $(includedir)/Ice/EndpointIF.h $(includedir)/Ice/Endpoint.h $(includedir)/Ice/UndefSysMacros.h $(includedir)/Ice/ObjectAdapterF.h $(includedir)/Ice/ReferenceF.h $(includedir)/Ice/OutgoingAsyncF.h $(includedir)/Ice/Current.h $(includedir)/Ice/ConnectionF.h $(includedir)/Ice/Identity.h $(includedir)/Ice/StreamF.h $(includedir)/Ice/CommunicatorF.h $(includedir)/Ice/Object.h $(includedir)/Ice/IncomingAsyncF.h $(includedir)/Ice/Outgoing.h $(includedir)/IceUtil/Monitor.h $(includedir)/IceUtil/Cond.h $(includedir)/Ice/InstanceF.h $(includedir)/Ice/BasicStream.h $(includedir)/Ice/ObjectFactoryF.h $(includedir)/Ice/Buffer.h $(includedir)/Ice/Protocol.h $(includedir)/Ice/StringConverter.h $(includedir)/Ice/Plugin.h $(includedir)/Ice/LoggerF.h $(includedir)/IceUtil/Unicode.h $(includedir)/Ice/Incoming.h $(includedir)/Ice/ServantLocatorF.h $(includedir)/Ice/ServantManagerF.h $(includedir)/Ice/Direct.h $(includedir)/Ice/LocalException.h $(includedir)/Ice/BuiltinSequences.h $(includedir)/Ice/ObjectFactory.h $(includedir)/IceUtil/Iterator.h $(includedir)/IceUtil/ScopedArray.h
+Test.cpp: Test.ice
+Test.ice: $(SLICE2CPP) $(SLICEPARSERLIB)
diff --git a/cpp/test/Ice/defaultServant/.gitignore b/cpp/test/Ice/defaultServant/.gitignore
new file mode 100644
index 00000000000..505a9066685
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/.gitignore
@@ -0,0 +1,6 @@
+// Generated by makegitignore.py
+
+// IMPORTANT: Do not edit this file -- any edits made here will be lost!
+client
+Test.cpp
+Test.h
diff --git a/cpp/test/Ice/defaultServant/AllTests.cpp b/cpp/test/Ice/defaultServant/AllTests.cpp
new file mode 100644
index 00000000000..0ff1da9a5a8
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/AllTests.cpp
@@ -0,0 +1,158 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. 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 <Ice/Ice.h>
+#include <TestCommon.h>
+#include <TestI.h>
+
+using namespace std;
+using namespace Test;
+
+void
+allTests(const Ice::CommunicatorPtr& communicator)
+{
+ Ice::ObjectAdapterPtr oa = communicator->createObjectAdapterWithEndpoints("MyOA", "tcp -h localhost");
+ oa->activate();
+
+ Ice::ObjectPtr servant = new MyObjectI();
+
+ //
+ // Register default servant with category "foo"
+ //
+ oa->addDefaultServant(servant, "foo");
+
+ //
+ // Start test
+ //
+ cout << "testing single category... " << flush;
+
+ Ice::ObjectPtr r = oa->findDefaultServant("foo");
+ test(r == servant);
+
+ r = oa->findDefaultServant("bar");
+ test(r == 0);
+
+ Ice::Identity identity;
+ identity.category = "foo";
+
+ string names[] = { "foo", "bar", "x", "y", "abcdefg" };
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ prx->ice_ping();
+ test(prx->getName() == names[idx]);
+ }
+
+ identity.name = "ObjectNotExist";
+ MyObjectPrx prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ identity.name = "FacetNotExist";
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::FacetNotExistException&)
+ {
+ // Expected
+ }
+
+ identity.category = "bar";
+ for(int idx = 0; idx < 5; idx++)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+
+ try
+ {
+ prx->ice_ping();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ try
+ {
+ prx->getName();
+ test(false);
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+ }
+
+ oa->removeDefaultServant("foo");
+ identity.category = "foo";
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ try
+ {
+ prx->ice_ping();
+ }
+ catch(const Ice::ObjectNotExistException&)
+ {
+ // Expected
+ }
+
+ cout << "ok" << endl;
+
+ cout << "testing default category... " << flush;
+
+ oa->addDefaultServant(servant, "");
+
+ r = oa->findDefaultServant("bar");
+ test(r == 0);
+
+ r = oa->findDefaultServant("");
+ test(r == servant);
+
+ for(int idx = 0; idx < 5; ++idx)
+ {
+ identity.name = names[idx];
+ prx = MyObjectPrx::uncheckedCast(oa->createProxy(identity));
+ prx->ice_ping();
+ test(prx->getName() == names[idx]);
+ }
+
+ cout << "ok" << endl;
+}
diff --git a/cpp/test/Ice/defaultServant/Client.cpp b/cpp/test/Ice/defaultServant/Client.cpp
new file mode 100644
index 00000000000..0b5ffe9cca6
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Client.cpp
@@ -0,0 +1,57 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. 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 <Ice/Ice.h>
+#include <TestCommon.h>
+#include <Test.h>
+
+using namespace std;
+using namespace Test;
+
+int
+run(int argc, char* argv[], const Ice::CommunicatorPtr& communicator)
+{
+ void allTests(const Ice::CommunicatorPtr&);
+ allTests(communicator);
+
+ return EXIT_SUCCESS;
+}
+
+int
+main(int argc, char* argv[])
+{
+ int status;
+ Ice::CommunicatorPtr communicator;
+
+ try
+ {
+ communicator = Ice::initialize(argc, argv);
+ status = run(argc, argv, communicator);
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+
+ if(communicator)
+ {
+ try
+ {
+ communicator->destroy();
+ }
+ catch(const Ice::Exception& ex)
+ {
+ cerr << ex << endl;
+ status = EXIT_FAILURE;
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/test/Ice/defaultServant/Makefile b/cpp/test/Ice/defaultServant/Makefile
new file mode 100644
index 00000000000..928ecf67c5d
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Makefile
@@ -0,0 +1,33 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. 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 = ../../..
+
+CLIENT = client
+
+TARGETS = $(CLIENT)
+
+OBJS = Test.o \
+ TestI.o \
+ Client.o \
+ AllTests.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+SLICE_SRCS = Test.ice
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. -I../../include $(CPPFLAGS)
+
+$(CLIENT): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
+
+include .depend
diff --git a/cpp/test/Ice/defaultServant/Makefile.mak b/cpp/test/Ice/defaultServant/Makefile.mak
new file mode 100644
index 00000000000..65486d149cc
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Makefile.mak
@@ -0,0 +1,39 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2009 ZeroC, Inc. 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 = ..\..\..
+
+CLIENT = client.exe
+
+TARGETS = $(CLIENT)
+
+COBJS = Test.obj \
+ TestI.obj \
+ Client.obj \
+ AllTests.obj
+
+SRCS = $(COBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. -I../../include $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(GENERATE_PDB)" == "yes"
+PDBFLAGS = /pdb:$(CLIENT:.exe=.pdb)
+!endif
+
+$(CLIENT): $(COBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(SETARGV) $(COBJS) $(PREOUT)$@ $(PRELIBS)$(LIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q Test.cpp Test.h
+
+!include .depend
diff --git a/cpp/test/Ice/defaultServant/Test.ice b/cpp/test/Ice/defaultServant/Test.ice
new file mode 100644
index 00000000000..46398613058
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/Test.ice
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. 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
+
+module Test
+{
+
+interface MyObject
+{
+ string getName();
+};
+
+};
+
+#endif
diff --git a/cpp/test/Ice/defaultServant/TestI.cpp b/cpp/test/Ice/defaultServant/TestI.cpp
new file mode 100644
index 00000000000..50d2f49fc1f
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/TestI.cpp
@@ -0,0 +1,45 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. 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 <Ice/Ice.h>
+#include <TestI.h>
+
+using namespace std;
+
+void
+MyObjectI::ice_ping(const Ice::Current& current) const
+{
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw Ice::FacetNotExistException(__FILE__, __LINE__);
+ }
+}
+
+std::string
+MyObjectI::getName(const Ice::Current& current)
+{
+ string name = current.id.name;
+
+ if(name == "ObjectNotExist")
+ {
+ throw Ice::ObjectNotExistException(__FILE__, __LINE__);
+ }
+ else if(name == "FacetNotExist")
+ {
+ throw Ice::FacetNotExistException(__FILE__, __LINE__);
+ }
+
+ return name;
+}
diff --git a/cpp/test/Ice/defaultServant/TestI.h b/cpp/test/Ice/defaultServant/TestI.h
new file mode 100644
index 00000000000..7731e95be90
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/TestI.h
@@ -0,0 +1,23 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2009 ZeroC, Inc. 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_I_H
+#define TEST_I_H
+
+#include <Test.h>
+
+class MyObjectI : virtual public Test::MyObject
+{
+public:
+
+ virtual void ice_ping(const Ice::Current&) const;
+ virtual std::string getName(const Ice::Current&);
+};
+
+#endif
diff --git a/cpp/test/Ice/defaultServant/run.py b/cpp/test/Ice/defaultServant/run.py
new file mode 100755
index 00000000000..e2a84c8cd83
--- /dev/null
+++ b/cpp/test/Ice/defaultServant/run.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice-E is licensed to you under the terms described in the
+# ICEE_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 "can't find toplevel directory!"
+sys.path.append(os.path.join(path[0]))
+from scripts import *
+
+client = os.path.join(os.getcwd(), "client")
+
+TestUtil.simpleTest(client)